将不同类型的集合与LINQ相结合

时间:2014-04-20 00:22:52

标签: c# linq

我们说我有这两个数组:

const int length = 5;
var ints = new int[length] { 1, 2, 3, 4, 5 };
var strings = new string[length] { "s1", "s2", "s3", "s4", "s5" };

我想循环使用这些而不是这个

for (var index = 0; index < length; index++)
{
    var i = ints[index];
    var s = strings[index];
    DoSomething(i, s);
}

我想知道我是否可以使用LINQ以某种方式实现这样的目标

var items = ... i in ints
            ... s in strings
            select new { I = i, S = s };

foreach (var item in items)
{
    DoSomething(item.I, item.S);
}

像这样做嵌套的from并不起作用

var items = from i in ints
            from s in strings
            select new { I = i, S = s };

因为那将为每个外部迭代重复内部from

4 个答案:

答案 0 :(得分:5)

你想要linq Zip。例如,请检查此网站http://jesseliberty.com/2011/06/13/the-linq-zip-operator/

我还是要添加一个例子来指出一些问题。 Zip总是会达到最短的长度。即使是6的整数,它仍然会返回5。我知道在你的例子中你有相同的但只是传递有关linq的Zip的信息。

var ints = new int[] { 1, 2, 3, 4, 5, 6 };
var strings = new string[] { "s1", "s2", "s3", "s4", "s5" };
var zipper = ints.Zip(strings, (i, s) => new {i, s});

答案 1 :(得分:5)

正如@CharlesNRice所建议的,您可以像这样使用LINQ Zip:

var items = ints.Zip(strings, (i, s) => new {I = i, S = s});

答案 2 :(得分:3)

我看到人们创建了一个新对象,但没有人展示如何调用DoSomething。

我相信这就是你想要的:

ints.Zip(strings, (i,s) => DoSomething(i,s));

正如Grant所指出的,如果DoSomething返回void,则需要以下内容:

ints.Zip(strings, (i,s) => { DoSomething(i,s); return 0;} );

记住Linq懒惰也很重要!在实际导致此代码运行之前,不会发生任何事情。例如:

var a = ints.Zip(strings, (i,s) => { DoSomething(i,s); return 0;} );

不会导致调用DoSomething。然而

a.ToList();

a.Count();

将导致为所有值调用DoSomething。

您也可以将ToList()或Count()添加到第一个语句的末尾,这是您问题的最佳答案:

ints.Zip(strings, (i,s) => { DoSomething(i,s); return 0;} ).Count();

答案 3 :(得分:2)

这也可以使用Select方法完成:

ints.Select((x,idx) => new { I = x, S = strings[idx] });