Reputation: 1381
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 ?
Upvotes: 2
Views: 302
Reputation: 13972
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()));
Upvotes: 0
Reputation: 149020
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.
Upvotes: 3