Reputation: 484
public class Person
{
public string Email {get; set;}
public string Name {get; set;}
}
public Report : Dictionary<string, string>
{
public Report()
{
List<Person> list = getData(); // filled with Person's
var realList = list.Where(x => x.Name != "test");
foreach( var i in realList)
{
this.Add(i.Email,i.Name);
}
}
}
I tried to simplify my code to get down to the question. Basically I have a list of Persons and I want to get a sub list of that and then for each element in the sub list I want to add it to this dictionary which is the class.
My question: Is there a way to get rid of that foreach statement and achieve the same effect with in the linq statement above. Because it seems silly to me to go through the list once and then through the sub list. So what would be good if during the linq statement if x.Name is not equal to test then it adds it to the dictionary.
Upvotes: 5
Views: 2519
Reputation: 12534
Even though there are some nice answers already here how to convert your list directly to a dictionary, they don't really answer the original question, because you can't re-assign the this
variable (for classes it is read-only in C#) and you will have to iterate over the newly created dictionary to add elements from it to your this
dictionary.
I usually solve this problem by materializing the LINQ expression to a List and using ForEach()
method of the list (that also accepts lambda-expressions) to populate another structure.
Here isthea sample code:
list
.Where(x => x.Name != "test") // your condition
.ToList() // turns expression to list
.ForEach(a => this.Add(a.Email, a.Name)); // populating dictionary
You can have several conditions before ToList()
invocation, just in case you want to exclude the values that are already in the dictionary.
Upvotes: 0
Reputation: 564551
My question: Is there a way to get rid of that foreach statement and achieve the same effect with in the linq statement above. Because it seems silly to me to go through the list twice
You don't go through the list twice in your code - the list is only enumerated once, as LINQ uses deferred execution. This is likely the best way to achieve this.
If you didn't subclass a dictionary, however, and encapsulated one instead, you could use ToDictionary
to create the encapsulated dictionary:
List<Person> list = getData(); // filled with Person's
Dictionary<string,string> people = list
.Where(x => x.Name != "test")
.ToDictionary(x => x.Email, x => x.Name);
Upvotes: 17