如何在LINQ中使用额外的int参数Where()

时间:2016-01-09 08:50:51

标签: c# linq lambda where func

请注意,这不是delegates一般的问题。此外,我没有看到docs而没有更明智。

在LINQ中,我可以使用类似的东西。

using(Model model = new Model())
{
   return model.Things
               .Where(thing => thing.IsGood);
}

我可以看到返回类型(运算符的左对象)的类型为Thing,条件(运算符的右对象)的类型为bool。 Intellisense告诉我,我可以从这两个中挑选,我对第二个感到困惑。

Func<Thing, bool>  
Func<Thing, int, bool>

我假设lambda运算符只是实际调用的语法糖。那是对的吗?如果是这样,那个整数在那里做什么,我该如何指定呢?

5 个答案:

答案 0 :(得分:4)

来自docs for this overload

  

谓词

     

输入:cp /temorary/WordPress/*.php /new/directory/ cp /temporary/WordPress/*.css /new/directory/ ...

     

测试条件的每个源元素的函数;函数的第二个参数表示源元素的索引。

这表示整数是元素的索引。

所以,

System.Func<TSource, Int32, Boolean>
例如,

仅返回每个第二个元素。上面链接的文档有一个稍微复杂的用例示例,它涉及两个参数。

我不确定这只是一个拼写错误,但您链接的文档似乎是针对不包含此参数的重载,这可能解释了为什么您无法找到解释的原因它

答案 1 :(得分:2)

正如评论中所提到的,文档说明了第二个过度: -

  

根据谓词过滤一系列值。每个元素都是   index用在谓词函数的逻辑中。

以下是reference code,我想会向你说清楚: -

public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, 
                                                   Func<TSource, int, bool> predicate) 
{
    if (source == null) throw Error.ArgumentNull("source");
    if (predicate == null) throw Error.ArgumentNull("predicate");
    return WhereIterator<TSource>(source, predicate);
}

static IEnumerable<TSource> WhereIterator<TSource>(IEnumerable<TSource> source, 
                                                   Func<TSource, int, bool> predicate) 
{
   int index = -1;
   foreach (TSource element in source) {
       checked { index++; }
       if (predicate(element, index)) yield return element;
   }
}

您可以在foreach语句中看到我们提供的索引是如何使用的。因此,我们可以将谓词用作: -

.Where((thing, index) => thing.SomeIntProperty <= index * 2);

答案 2 :(得分:2)

使用示例说明而不是简单地引用MSDN帮助页面:

拿这段代码:

var list = new List<string> { "a", "b", "c" }
var index = 0;
foreach (var item in list)
{
    if (item == "b" && index == 1) {
        Console.WriteLine(item);
    }
    index++;
}

变为

var list = new List<string> { "a", "b", "c" }

var items = list.Where((item, index) => item == "b" && index == 1)

foreach (var item in items) {
    Console.WriteLine(item);
}

(你可以使用其他linq命令用于写信等,这是为了说明Where

答案 3 :(得分:1)

正如MSDN中所述:

  

根据谓词过滤一系列值。每个元素都是   index用在谓词函数的逻辑中。

什么时候需要?例如,您可能需要所有具有偶数索引的元素:

return model.Things
    .Where((thing, index) => index % 2 == 0);

此外,在将来,您可以使用提供.net源代码的this web site来更快地找到并学习这些内容。例如,以下是Where()方法的重叠实现:

 public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            return WhereIterator<TSource>(source, predicate);
        }

我们可以看到它返回WhereIterator方法:

static IEnumerable<TSource> WhereIterator<TSource>(IEnumerable<TSource> source, Func<TSource, int, bool> predicate) {
            int index = -1;
            foreach (TSource element in source) {
                checked { index++; }
                if (predicate(element, index)) yield return element;
            }
        }

我们可以看到实际Linq使用foreach循环,并通过将index变量递增1来获取当前元素的索引。

答案 4 :(得分:0)

Where 上有两篇MSDN文章。您链接到The onethis one

使用语法如下:

using(Model model = new Model())
{
  return model.Things
    .Where((thing, counter) => thing.IsGood < counter);
}

如你所见,这个特殊情况没什么意义,我从来不需要使用它。然而,如果需要,它就在那里。您可以在提供的链接中找到一个示例。