简体   繁体   中英

Merge Two Lists of Lists

I would like to merge two Lists of Lists of a certain class that share the same key

Let's say that I have the class :

public class Album {

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

}

and two Lists of Lists :

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

I would like to merge the lists in AlbumList1 and AlbumList2 that have the same Key .

For example if a List is called "Genre1" and another is called "Genre1" i would like to merge those two lists to create a unique list .

How can I perform this ?

It would probably look a bit like this:

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

Or perhaps like this:

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

However, I'd also recommend you consider refactoring the code to use a IDictionary<string, IEnumerable<Album>> or an ILookup<string, Album> instead.

Seems like you might want to refactor that outer list a bit out to a class. Something like this:

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; }
}

After that, you can then create a comparer (simplified)

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

Then, it's a simple join - adding back in the missing Genres.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM