使用Linq查询截断集合

时间:2012-05-11 13:16:21

标签: linq lambda

我想将一部分集合提取到另一个集合中。 我可以使用for循环轻松地做同样的事情,但我的linq查询不能同样工作。 我是Linq的新手,所以请帮我纠正一下查询(如果可能,请附上说明/初学者教程链接)

传统的做法:

Collection<string> testColl1 = new Collection<string> {"t1", "t2", "t3", "t4"};
Collection<string> testColl2 = new Collection<string>();

for (int i = 0; i < newLength; i++)
{
    testColl2.Add(testColl1[i]);
}

其中testColl1是来源&amp; testColl2是count = newLength所需的截断集合。

我使用了以下linq查询,但它们都没有工作......

var result = from t in testColl1 where t.Count() <= newLength select t;
            var res = testColl1.Where(t => t.Count() <= newLength);

4 个答案:

答案 0 :(得分:3)

使用Enumerable.Take

var testColl2 = testColl1.Take(newLength).ToList();

请注意,for循环与使用Take的版本之间存在语义差异。如果for中的项目少于IndexOutOfRangeException,则newLength循环将抛出testColl1个异常,而Take版本将默默忽略此事实并返回尽可能多的项目newLength项。

答案 1 :(得分:2)

正确的方法是使用Take

var result = testColl1.Take(newLength);

使用Where的等效方式是:

var result = testColl1.Where((i, item) => i < newLength);

这些表达式会生成IEnumerable,因此您可能还希望在结尾附加.ToList().ToArray()

两种方式都比原始实现少了一个项目,因为它更自然(例如,如果newLength == 0没有项目应该返回)。

答案 2 :(得分:1)

您可以将for循环转换为以下内容:

testColl1.Take(newLength)

答案 3 :(得分:1)

使用Take

var result = testColl1.Take(newLength);

此扩展方法返回集合中的前N个元素,其中N是您传递的参数,在本例中为newLength