Why does this return zero results? - c#

I have a List<List<string>> and when I try to search with the List<string> it returns no results.
Any ideas?
Thanks
List<List<string>> test = new List<List<string>>();
List<string> ff = new List<string>();
ff.Add("1");
ff.Add("ABC 1");
test.Add(ff);
ff = new List<string>();
ff.Add("2");
ff.Add("ABC 2");
test.Add(ff);
var result = test.Where(x=>x.Contains("ABC"));
//result.Count(); is 0

Neither of your lists contains the element "ABC".
If you want to find the lists that have an element that contains "ABC" as a substring you can do this:
var result = test.Where(x => x.Any(y => y.Contains("ABC")));

Its because you are doing a list of a list and not going far enough down in your selection. Something like this should give you two results:
var result = test.Select(x => x.Where(y => y.Contains("ABC")));

none of your lists contain the string "ABC". It doesn't search the string when you use that contains function, it just matches the whole string. If you want to search for a partial string, then you have to use something like the following:
var result = test.Where(x => x.Where(y => y.Contains("ABC").Count() > 0));

Related

Compare if elements in string array exists in another list c#

I have an string array and a list of string. For example,
string[] stringArray = {"car", "bike", "truck"};
List<string> stringList = new List<string>{"car_blue", "car_red", "truck_yellow", "ship_black", "rocket_orange"};
From the array and list, I want to compare stringArray with stringList and retrieve items that are in the stringArray and is also part of the stringList.
Eg: the items retrieved should be, 'car_blue', 'car_red' and 'truck_yellow'?
You could use LINQ' Where to filter the stringList using the parts before the _:
var result = stringList.Where(x => stringArray.Contains(x.Split('_')[0]));
You have to Split by _ to get all tokens, then you can use Intersect...Any:
var itemsInBoth = stringList.Where(s => stringArray.Intersect(s.Split('_')).Any());
If you want to ignore the case, so also accept Car_Yellow:
var itemsInBoth = stringList.Where(s => stringArray.Intersect(s.Split('_'), StringComparer.OrdinalIgnoreCase).Any());
The Best way where you don't have to use split is
string[] oneMinEnabledTime = stringList.Where(x => stringArray.Any(ele => x.ToLower().Contains(ele.ToLower()))).ToArray();
or if you want list
List<string> oneMinEnabledTime = stringList.Where(x => stringArray.Any(ele => x.ToLower().Contains(ele.ToLower()))).ToList();

Search for occurance of a list in a string on C#

The base is a list of approx 2000 strings. Most of them single word. Some of them two and three words.
Now my query is a string (4 to 9 words). I have to find out which all of these 2000 words or cluster of words appears in this string.
As of now I am using for loop, its working for me, but its taking a lot of time. What is the most effective way of doing it??
You have to use a loop, there is no other way to process multiple items.
Maybe this is more efficient(difficult to compare without code):
string[] words = your4to9Words.Split();
List<string> appearing = stringList
.Where(s => s.Split().Intersect(words).Any())
.ToList();
You can try a HashSet
place your 2000 words into this HashSet, and then use HashSet.Compare
HashSet<string> h = new HashSet<string>(); //load your dictionary here
if (h.Contains(word))
console.log("Found");
This should be what you are looking for:
var binOf2000Words = new List<string>();
var binOf4To9Words = new List<string)();
// And at this point you have some code to populate your lists.
// We now need to cater for the fact that some of the items in the 2000Words bin will actually be strings with more than one word...
// We'll do away with that by generating a new list that only contains single words.
binOf2000Words = binOf2000Words.SelectMany(s => s.Split(' ')).Distinct().ToList();
var result = binOf2000Words.Intersect(binOf4To9Words).Distinct().ToList();
You can try something like this:
List<string> binOf2000Words = new List<string>
{
"One",
"Two",
"Three Four"
};
string query = "One Four Three";
var queryLookup = query.Split(' ').ToLookup(v => v, v => v);
var result = binOf2000Words.SelectMany(s => s.Split(' ')).Distinct().Where(w => queryLookup.Contains(w));

Does string contain an Item in a list, and get that index

I am trying to work something out, I have a string, and a list
string mystring = "this is my string";
List<string> mylist = new List<string>();
int i = 0;
mylist.Add("yes");
mylist.Add("no");
mylist.Add("my");
mylist.Add("foobar");
I want to know does mystring contain (anywhere) an item in the mylist and which item (index) in mylist it is. There will be no repeats in the list either.
so the result of i should be 2 in the case of this example.
I could easily do this with a loop, but I was hoping for an easier "one liner" if you will.
You can do it in one line by using the overload of Select that includes the index:
string mystring = "this is my string";
List<string> mylist = new List<string>();
mylist.Add("yes");
mylist.Add("no");
mylist.Add("my");
mylist.Add("foobar");
var result = mylist.Select((s,i) => new {s, i})
.Where(si => mystring.Contains(si.s));
yields:
(1 item)
s i
---- ----
my 2
var indexes = mystring.Split()
.Where(w => mylist.Contains(w))
.Select(w => mylist.IndexOf(w))
.ToList();
you can't use a single int i as your list can contain 0+ words, so use an array or a List.
int i = mylist.IndexOf(mylist.FirstOrDefault(s => Regex.IsMatch(mystring, string.Format("(^| ){0}( |$)", s))));
This will give you the index of the first word in the list that appears in the string

How to use Linq to check if a list of strings contains any string in a list

I'm constructing a linq query that will check is a string in the DB contains any of the strings in a list of strings.
Something like.
query = query.Where(x => x.tags
.Contains(--any of the items in my list of strings--));
I'd also like to know how many of the items in the list were matched.
Any help would be appreciated.
Update: I should have mentioned that tags is a string not a list. And I am adding on a couple more wheres that are not related to tags before the query actually runs. This is running against entity framework.
EDIT: This answer assumed that tags was a collection of strings...
It sounds like you might want:
var list = new List<string> { ... };
var query = query.Where(x => x.tags.Any(tag => list.Contains(tag));
Or:
var list = new List<string> { ... };
var query = query.Where(x => x.tags.Intersect(list).Any());
(If this is using LINQ to SQL or EF, you may find one works but the other doesn't. In just LINQ to Objects, both should work.)
To get the count, you'd need something like:
var result = query.Select(x => new { x, count = x.tags.Count(tag => list.Contains(tag)) })
.Where(pair => pair.count != 0);
Then each element of result is a pair of x (the item) and count (the number of matching tags).
I've done something like this before:
var myList = new List<string>();
myList.Add("One");
myList.Add("Two");
var matches = query.Where(x => myList.Any(y => x.tags.Contains(y)));
like this:
List<string> list = new List<string>();
list.Add("One");
list.Add("Two");
var result = query.Where(x => list.Contains(x.tags));
I am not quite sure from your question if x.tags is a string or list, if it is a list Jon Skeet's answer is correct. If I understand you correctly though x.tags is a string of strings. If so then the solution is:
list.Any(x => x.tags.IndexOf(x) > -1)
to count them do
list.Count(x => x.tags.IndexOf(x) > -1)
var t = new List<string> { "a", "b", "c" };
var y = "a b d";
var res = y.Count(x => t.Contains(x.ToString()));
I faced a similar problem recently and here's how I managed to work it out:
var list = [list of strings];
if (list != null && list.Any())
{
queryable = queryable.Where(x => x.tags != null);
var tagQueries = new List<IQueryable<WhateverTheDbModelIs>>();
foreach (var element in list)
{
tagQueries.Add(queryable.Where(x => x.tags.Contains(element)));
}
IQueryable<WhateverTheDbModelIs> query = tagQueries.FirstOrDefault();
foreach (var tagQuery in tagQueries)
{
query = query.Union(tagQuery);
}
queryable = queryable.Intersect(query);
}
probably not the best option but something a less experienced developer can understand and use

Check if the Array has something like my Text

I have a array of strings . I need to check in the array if it has something like "abcd". How to achive this in C#. I tried using the
var pathBits = new[] {"abcde ","abcd &"};
var item ="abcd";
var results = Array.FindAll(pathBits, s => s.Equals(item ));
maybe something like this:
var result = pathBits.Any(y => y.Contains(item));
That will give you true if the array contains an item that has a value like item. If you want to select all those values you should use:
var result = pathBits.Where(y => y.Contains(item));
which will give you an IEnumerable of the items from the list that contain the value item.
When you say 'something like "abcd"' do you mean "Starts with" or "Contains"?
The current code will only find strings in pathBits which are exactly equal to item ("abcd" ?)
The general shape is fine but to find non-exact matches you need to change the predicate
e.g.
string[] src = new[] { "abcde", "abcd &" };
var results = Array.FindAll<string>(src, name => name.Contains("abcd"));
This can also be implemented using the Linq IEnumerable<> extensions
e.g.
string[] src = new[] { "abcde", "abcd &" };
var results = src.Where(name => name.Contains("abcd"));
hth,
Alan.
This might be of some use
string[] pathBits = { "abcde ", "abcd &" };
var item = "abcd";
if (pathBits.Contains(item)) ;
{
}
You cannot use
var pathbits = { "abcde ", "abcd &" };
Please let me know if you have any problem
Is this what your looking for?
string[] pathBits = { "abcde ", "abcd &", "222" };
var item = "abcd";
var results = Array.FindAll<string>(pathBits, s => s.Contains(item));
results will have 2 items.
I'm not sure exactly what you want, but this would get all array allements that contain the string "abcd" -
String[] pathBits = {"abcde ","abcd &"};
var item ="abcd";
var results = pathBits.Where(s => s.IndexOf("abcd") > -1);

Categories

Resources