System.Linq.Enumerable + d__3a ' 1(系统.LINQ foreach循环错误

本文关键字:系统 LINQ 错误 循环 foreach Enumerable Linq 3a System | 更新日期: 2023-09-27 18:16:31

我有一个列表,我试图从另一个列表中填充,其中我想组合一些数据并消除一些。

在原始列表中,数据看起来像这样:

 Id     Text      Description
  1      Apple     Red Delicious
  1      Apple     Green
  1      Apple     Granny 
  2      Tomato    Roma
  2      Tomato    Cherry   

我想在第二个列表中压缩这些信息,看起来像这样:

  Id    Text     Description
  1     Apple    Red Delicious, Green, Granny
  2     Tomato   Roma, Cherry 

我的类对象声明如下:

 [Serializable]
 public class Food
 {
     public int Id { get;set; }
     public string Text { get;set; }
     public string Description { get;set; } 
 }

我想循环遍历旧的列表在代码中我是这样做的:

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();

现在我得到System. linq . enumerable +d__3a ' 1[System. linq . enumerable]。错误,因为。take(),但如果我改变它只是。tostring(),我得到一个稍微不同的错误,但从相同的源System.linq。Enumerable,如果我用FirstOrDefault()和。distinct()也一样。

我想我理解的问题是,对于文本和描述它返回IEnumerable文本和描述,所以我没有得到我想要的实际值,我不确定我理解如何正确转换它。tolist()。访问这些值的正确方法是什么?

System.Linq.Enumerable + d__3a ' 1(系统.LINQ foreach循环错误

根据TakeSelect的结果调用ToString() -这不会做任何好事。不清楚为什么你在Description中显式地调用ToString,对于Text,你真的想要FirstOrDefaultFirst,因为你只想要第一个结果:

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();

基本上,在序列(IEnumerable<T>)上调用ToString()几乎是从不合适的。

这是GroupBy操作员的典型工作:

var newList = oldList.GroupBy(x => x.Id, 
                        (key, values) => 
                           new Food() {
                             Id = key,
                             Text = values.First().Text,
                             Description = string.Join(", ", 
                                              values.Select(v => v.Description))
                            })
                     .SelectMany(x => x)
                     .ToList();

我认为你的方法可能过于复杂了。

这是一个非常粗略地拼凑在一起的示例(如果你喜欢,你可以在LinqPad中运行它),但它使用.GroupBy来解决同样的问题…

var l = new List<Tuple<int, string, string>>();
l.Add(Tuple.Create(1, "Apple", "Red Delicious"));
l.Add(Tuple.Create(1, "Apple", "Green"));
l.Add(Tuple.Create(1, "Apple", "Granny"));
l.Add(Tuple.Create(2, "Tomato", "Roma"));
l.Add(Tuple.Create(2, "Tomato", "Cherry"));
var res = l.GroupBy(t => t.Item2).Select(g => new { Id = g.First().Item1, Text = g.Key, Description = string.Join(", ", g.Select(i => i.Item3)) });
res.Dump(); // Linqpad output