创建一个字典,其中键表示来自列表的元素。

3

我想创建一个字典 Dictionary,其中每个 Key 表示来自 List 的元素。这个字典必须包括每个列表元素。

例如:
一部电影有一组演员。

现在我想要一个演员参演的电影列表。如果电影有多个演员,则每个演员应该有自己的电影列表。

我的数据结构如下:

public class MovieData
{
    public List<string> Actors { get; set;}
    public string Title { get; set; }
    public DateTime ReleaseDate { get; set; }
    public string FilePath { get; set; }
}

一个小示例来说明这一点:
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" }};

期望的结果应该是这样的:
Alice Stevens => { "Movie1", "Movie2" }
Bob Smith     => { "Movie1" }
John Doe      => { "Movie3" }

我想到了以下的代码,但它只关注列表中的第一个演员(FirstOrDefault())。因此,列表中的其他演员被忽略了。

var actorMovieList = movieDataList
  .ToLookup(movie => movie
                       .Actors
                       .FirstOrDefault(), movie => movie);

我该如何将其他演员包含在列表中?我必须在lambda内部遍历演员列表,但我不知道该怎么做。

4个回答

5

您可以尝试使用 SelectMany 来将初始的 List<List<string>>展开”

{actor, title}

记录数据,然后使用 GroupBy 按照 actor 分组并将它们放入所需的字典中:

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

3
你可以先使用 SelectMany 方法将 movieDataList 摊平成演员和电影标题的集合,然后再将其与 ToLookup 方法结合使用。这样可以在最终结果中包含所有作者。
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)}");
}

输出结果如下所示:

在此输入图片描述


2

这里有一个快速解决方案,可以提供所需的结果:

假设您有一个像这样的电影数据列表:

var movieDataList = new List<MovieData> { movie1, movie2, movie3 };

首先,让我们提取所有演员:
// NOTE: Used ToHashSet() in the end to avoid the duplicates in the names
var actors = movieDataList
    .SelectMany(item => item.Actors)
    .ToHashSet();

现在让我们创建一个包含演员姓名和电影列表的字典。
var allActorMovieList = new Dictionary<string, List<string>>();
foreach (var actor in actors)
{
    // List of the movies of the actor
    var actorMovieList = movieDataList
        .Where(movieData => movieData.Actors.Contains(actor))
        .Select(movieData => movieData.Title)
        .ToList();

    allActorMovieList.Add(actor, actorMovieList);
}

现在,allActorMovieList 包含所有演员和他们的电影。

2
var flatQuery = 
  from movie in movies
  from actor in movie.Actors
  select new {movie, actor};

var lookup = flatQuery.ToLookup(
  pair => pair.actor,
  pair => pair.movie.Title);

var aliceStevensMovies = lookup["Alice Stevens"].ToList();
var amyBMovies = lookup["Amy B"].ToList(); //empty, not keyNotFound

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接