I want to create a Dictionary where the Keys are representing elements from a List. Each list element has to be present in this dictionary.
Example:
A movie has a list of actors.
Now I want a list of movies the actor acted in. If the movies have more than one actor, each actor should have the movie in their own list.
I have a data strucuture like this:
public class MovieData
{
public List<string> Actors { get; set;}
public string Title { get; set; }
public DateTime ReleaseDate { get; set; }
public string FilePath { get; set; }
}
A small example to illustrate this:
var movie1 = new MovieData {
Title = "Movie1",
Actors = new List<string> { "Bob Smith", "Alice Stevens"}};
var movie2 = new MovieData {
Title = "Movie2",
Actors = new List<string> { "Alice Stevens"}};
var movie3 = new MovieData {
Title = "Movie3",
Actors = new List<string> { "John Doe" }};
The desired result should look like this:
Alice Stevens => { "Movie1", "Movie2" }
Bob Smith => { "Movie1" }
John Doe => { "Movie3" }
I came up with the following code, but it only pays attention to the first actor in the list (FirstOrDefault()). So other actors in the list are ignored.
var actorMovieList = movieDataList
.ToLookup(movie => movie
.Actors
.FirstOrDefault(), movie => movie);
How can I include the other actors in the list? I have to iterate through the actor list inside of the lambda, but I don't know how.
You can try SelectMany to flatten the initial List<List<string>> into
{actor, title}
records and then put GroupBy to group them by actor into required dictionary:
var result = movieDataList
.SelectMany(movie => movie
.Actors
.Select(actor => new { // from now we have flat cursor of
actor = actor, // {actor, title} records
title = movie.Title
}))
.GroupBy(record => record.actor, // ... which we group by actor:
record => record.title) // actor and movies (s)he played in
.ToDictionary(group => group.Key, // or ToLookUp()
group => group.ToList());
You can flatten the movieDataList first (using SelectMany method) into collection of actors and movie titles and then use ToLookup method with this collection. It allows you to include all authors in the final result
var movieDataList = new List<MovieData>() { movie1, movie2, movie3 };
var result = movieDataList
.SelectMany(m => m.Actors
.Select(a => new
{
Actor = a,
Movie = m.Title
}))
.ToLookup(pair => pair.Actor, pair => pair.Movie);
foreach (var item in result)
{
Console.WriteLine($"{item.Key} {string.Join(",", item)}");
}
The output will be the following

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With