How to search a list of objects using a specific property

I am trying to find a collection List<Word>

where Word

is my class with a property Name

and add each item contained in a given array of strings to the collection List<string>

. i.e.

class Word
    public string Name;//Name property

var words = new List<Word>();
var recognized = new List<Word>();


Here is the code I'm trying:

theSentence.Split(new[] {' '}).ToList().ForEach(s => words.Where(w => w.Name == s).ToList().ForEach(recognized.Add));


Is this code healthy? Is there a way to do it if(words.Contain(Name property))

in .NET?



source to share

4 answers

It's not a good idea for me, no. Just use LINQ more simply (and more efficiently):

var recognized = theSentence.Split(' ')
                            .Join(words, x => x, word => word.Name,
                                  (x, word) => word)


Or as a query expression:

var recognized = (from x in theSentence.Split(' ')
                  join word in words on x equals word.Name
                  select word)


(As an aside, I note that the property Name

"is actually just a public field. I hope this is a real property in your actual code :)

For this part:

Is there a way to do it if(words.Contain(Name property))

in .NET?

I would create a new set:

HashSet<string> wordNames = new HashSet<string>(words.Select(x => x.Name));


Then you can simply use:

if (wordNames.Contains(...))


... and it will be an O (1) operation (no hash collisions, etc.) instead of checking every word every time.

EDIT: Referring to this comment:

Is it possible that I can get the elements of the collection not found in Join and put them in another list ... Unrecognized List

Yes - if you are happy you only have one Word

with any given Name

, or you have overridden Equals

and GetHashCode

in Word

, you can use:

var unrecognized = words.Except(recognized).ToList();




Your current code does nothing. If you want to select words with an accessible name in a section, you can do the following:

var recognized = theSentence.Split(new[] {' '})
                           .SelectMany(x=>words.Where(y=>y.Name == x))


Also you can add a separate one to prevent redundant data.



Suppose you have a list of famous words:

var words = new List<Word>();


And you want to see what words are in the sentence:

string sentence = "The cat is on the table";


All you have to do is use LINQ like this:

var found = sentence.Split(' ').Where(word => words.Any(known => known.Name == word));


You are using LINQ incorrectly in your code because you are adding items to the list yourself, bypassing all the LINQ magic.

EDIT: Sorry, I didn't see you trying to get a wordlist! In this case, use the method Join

suggested by Jon Skeet. Alternatively, just add the statement Select

to the end and re-create the word class:

found.Select(a => new Word() { Name = a });




Do you mean:

        if (words.Count(n => n.Name == "name") > 0)





All Articles