I have a list that I am trying to populate from another list in which I want to combine some data and eliminate some.
In the original list the data looks like this:
Id Text Description
1 Apple Red Delicious
1 Apple Green
1 Apple Granny
2 Tomato Roma
2 Tomato Cherry
I want to condense this information in the second list to look like this:
Id Text Description
1 Apple Red Delicious, Green, Granny
2 Tomato Roma, Cherry
My class object is declared like this:
[Serializable]
public class Food
{
public int Id { get;set; }
public string Text { get;set; }
public string Description { get;set; }
}
So I want to loop through the old list and this is how I'm trying to do it in the code:
var ids = oldList.Select(i => i.Id).Distinct(); //get distinct list of ids (e.g. 1,2)
List<Food> newList = ids.Select(i => new Food(){
Id = i,
Text = oldList.Where(o => o.Id == i).Select(o => o.Text).Take(1).ToString(),
Description = string.Join(",", oldList.Where(o => o.Id == i).Select(o => o.Description).ToString())
}).ToList();
Right now I'm getting the System.Linq.Enumerable+d__3a`1[System.String] error because of .Take(), but if I change it just .ToString(), I get a slightly different error but from the same source System.linq.Enumerable, if I do FirstOrDefault() same thing, .Distinct() same thing.
I think I understand that the problem is that for Text and Description its returning IEnumerable for Text and Description so I'm not getting the actual values that I want and I'm not sure I understand how to correctly convert it .ToList(). What is the correct way to access these values?
You're calling ToString()
on the result of Take
and Select
- and that's not going to do anything nice. It's not clear why you're calling ToString
explicitly in Description
, and for Text
you really want FirstOrDefault
or First
instead, as you just want the first result:
List<Food> newList = ids.Select(i => new Food {
Id = i,
Text = oldList.Where(o => o.Id == i).Select(o => o.Text).FirstOrDefault(),
Description = string.Join(",", oldList.Where(o => o.Id == i)
.Select(o => o.Description))
}).ToList();
Basically, calling ToString()
on a sequence (IEnumerable<T>
) is almost never appropriate.
See more on this question at Stackoverflow