1

IEnumerable 的重载之一是:

public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, TResult> selector);

在选择器中,我希望包含源代码。我知道这听起来违反直觉,因为您首先提供了 Select 的源代码,但 JavaScript 也有类似的东西。我想在这里像这样的快速情况下使用它:

var greetings = new List<string> { "John", "Keith", "Sarah", "Matt" }.Select((name, index, source) => {
    if (name == source.First())
        return $"{name} (Todays Winner)";
    return name;
});

上面会报错,因为 Select 的 selector 参数没有返回 3 个值。只是当前对象和索引。我希望它包括来源。

我不想先单独创建列表,然后再对其执行 .first 。

这是我在扩展方面走了多远;我不确定如何实现它。

public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, TResult, IEnumerable<TSource>> selector)
{
    //not sure what to put in here, must be missing something simple ;(
}

更新

上述情况只是一个虚构的例子。我的实际情况需要使用.Last()not.First()所以索引不会有用,因为我们不知道最后一个索引是什么,而不是第一个是零。因此,我需要将源传回。

4

2 回答 2

2

这应该这样做:

public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TSource>, TResult> selector)
{
    using (var enumerator = source.GetEnumerator()) {
        for (var i = 0 ; enumerator.MoveNext() ; i++) {
            yield return selector(enumerator.Current, i, source);
        }
    }
}

请注意,您为selector参数编写了错误的类型。应该是Func<TSource, int, IEnumerable<TSource>, TResult>,不是Func<TSource, int, TResult, IEnumerable<TSource>>

如果你只是想检查一个元素是否是第一个,为什么不检查index == 0呢?

var greetings = new List<string> { "John", "Keith", "Sarah", "Matt" }.Select((name, index, source) => {
    if (index == 0)
        return $"{name} (Todays Winner)";
    return name;
});
于 2019-09-24T06:11:11.377 回答
2

这应该有效:

public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TSource>, TResult> selector)
{
        int index = 0;
        foreach(var item in source)
        {
            yield return selector(item, index, source);
            index++;   
        }
}
于 2019-09-24T06:13:34.323 回答