如何将两个列表合并成一个List<KeyValuePair<>>?

8

这里有两个列表:

List<string> files;
List<Filter> filters;

我希望结果像这样:

List<KeyValuePair<string, Filter>> fileFilterMap;

我尝试了几种方法(lambda表达式,linq)但都失败了。 我真的不想用 for(int i = 0; i< files.count; i++) 这个方法。

1
你想如何映射它们?使用索引0和索引0吗? - Kolky
1
为什么不用 for 循环?很可能它比其他方式更易读 并且 更高效。 - LukeH
1
人们似乎开始重新喜欢使用for循环,因为他们不知道所有LINQ功能。如果你看一下答案,大多数看起来非常神秘,但它是一个短的一行代码,使用Enumerable.Zip()函数即可实现。 - Stefan Paul Noack
@noah1989 哇!太棒了!喜欢这个功能)) 以前从未听说过。 - Oybek
7个回答

14

您可以使用:

List<KeyValuePair<string, Filter>> fileFilterMap =
  Enumerable.Range(0, files.Count)
  .Select(i => new KeyValuePair<string, Filter>(files[i], filters[i]))
  .ToList();

或者:

List<KeyValuePair<string, Filter>> fileFilterMap =
  Enumerable.Zip(
    files,
    filters,
    (file, filter) => new KeyValuePair<string, Filter>(file, filter)
  )
  .ToList();

1
为什么要重新发明轮子?这就是Enumerable.Zip所做的事情,但有一些缺陷:例如,当files.Count > filters.Count时会发生什么? - Stefan Paul Noack
@noah1989:没错,我没有考虑到那个。我会添加的。 - Guffa
Enumerable.Zip是针对.Net 4的。3.5或更低版本有类似的功能吗? - Odys
@odyodyodys:是的,请使用第一种选项。 - Guffa

6
请查看Enumerable.Zip
var fileFilterMap = Enumerable.Zip(files, filters, (file, filter) => new KeyValuePair(file, filter));

到目前为止,这是我最喜欢的解决方案。整洁而简单!谢谢 - Odys

3
假设你的意思是两个列表最初已经同步,那么
var fileFilterMap = files.Select((s, i) => new KeyValuePair<string, int>(s, filters[i])).ToList();

将会工作。

话虽如此,for(int i; i != files.Count; ++i)有什么问题呢?我认为这更优秀(稍微快一些,更加清晰明了)。


1

认为您的Filter类包含了属性Prop,因此在这里进行了条件限制,以下是摘录。

    public class Filter {
        public String Prop { get; set; }
    }
    static void Main(string[] args) {

        var strings = new List<String>();
        var filters = new List<Filter>();

        var result = strings.Select(x => new KeyValuePair<string, Filter>(x,filters.FirstOrDefault(y => y.Prop == x)))
            .ToList();

        Console.ReadLine();
    }

1

这是一个可能的解决方案,虽然它不太美观...(因为它对文件中的每个项目进行了IndexOf查找。并且需要files中的每个条目都是唯一的。)

List<string> files = new List<string>();
List<Filter> filters = new List<Filter>();

List<KeyValuePair<string, Filter>> fileFilterMap =
     files.ToDictionary(
          file => file, // key selector
          file => filters[files.IndexOf(file)] // item selector
     ).ToList();

1
List<KeyValuePair<string, Filter>> fileFilterMap = new List<KeyValuePair<string, Filter>>();
files.All(a => { fileFilterMap.Add(new KeyValuePair<string, Filter>(a, filters[files.IndexOf(a)])); return true; });

1
var fileFilterMap = files.Zip(filters, (file, filter) => new KeyValuePair<string,Filter>(file, filter)).ToList();

我更喜欢这个答案。精准简洁...感谢您提出这个问题... - Alvin Quezon

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