【问题标题】:Merge Two Lists of Lists合并两个列表列表
【发布时间】:2014-02-21 18:06:31
【问题描述】:

我想合并共享相同键的某个类的两个列表列表

假设我有课:

public class Album {

public string Name { get ; set; }
    public string Genre{ get ; set; }

}

和两个列表列表:

public List<List<Album>>  AlbumList1 ;
public List<List<Album>>  AlbumList1 ;

我想合并 AlbumList1 和 AlbumList2 中具有相同 Key 的列表。

例如,如果一个列表名为“Genre1”而另一个名为“Genre1”,我想合并这两个列表以创建一个唯一列表。

我该怎么做?

【问题讨论】:

  • 关键是什么? NameGenre?
  • 列表有索引而不是键......你必须解释你想如何匹配它们,以便我编写有用的代码。
  • 我很困惑 - 你想要Albums 的单个列表还是List&lt;Albums&gt;s 的单个列表?
  • key 不是这个,它是列表的名称,例如,如果我将列表称为“example”,则键将是 example List Example ;

标签: c# .net linq list


【解决方案1】:

它可能看起来有点像这样:

var results = albumList1
    .SelectMany(l => l)
    .Concat(albumList2.SelectMany(l => l)
    .GroupBy(l => l.Name, g => g.ToList())
    .ToList();

或者像这样:

var results = albumList1
    .Join(albumList2, 
          l => l[0].Name,
          l => l[0].Name, 
          (l1, l2) => l1.Concat(l2).ToList())
    .ToList();

不过,我还建议您考虑重构代码以改用IDictionary&lt;string, IEnumerable&lt;Album&gt;&gt;ILookup&lt;string, Album&gt;

【讨论】:

    【解决方案2】:

    似乎您可能想将外部列表重构为一个类。像这样的:

    public class Genre
    {
        public string Name { get; set; }
        public List<Album> Albums { get; set; }
    }
    
    public class Album
    {
        public string Genre { get; set; }
        public string Name { get; set; }
    }
    

    之后,您可以创建一个比较器(简化)

    public class GenreComarer : IEqualityComparer<Genre>
    {
        public bool Equals(Genre x, Genre y)
        {
            return x.Name.Equals(y.Name);
        }
    
        public int GetHashCode(Genre obj)
        {
            return obj.Name.GetHashCode();
        }
    }
    
    public class AlbumComarer : IEqualityComparer<Album>
    {
        public bool Equals(Album x, Album y)
        {
            return x.Name.Equals(y.Name);
        }
    
        public int GetHashCode(Album obj)
        {
            return obj.Name.GetHashCode();
        }
    }
    

    然后,这是一个简单的连接 - 重新添加缺少的流派。

        List<Genre> unified = list1.Join(list2, 
            e => e.Name, 
            e => e.Name, 
            (genre1, genre2) => new Genre 
                { 
                    Name = genre1.Name, 
                    Albums = genre1.Albums.Union(genre2.Albums, new AlbumComarer()).ToList() 
                }
            ).ToList();
        unified.AddRange(list2.Except(list1, new GenreComarer()));
        unified.AddRange(list1.Except(list2, new GenreComarer()));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-23
      • 1970-01-01
      • 2014-03-19
      • 2014-01-27
      • 1970-01-01
      相关资源
      最近更新 更多