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的选择器参数未返回3个值。只是当前对象和索引。我希望它包含来源。
我不想先单独创建列表,然后再对其进行处理。
这是我对扩展程序所做的努力;我不确定如何实现。
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()
而不是.First()
,因此索引将无用,因为我们不知道最后一个索引是什么,而不是首先是零。因此,我需要将源传递回去。
答案 0 :(得分: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;
});
答案 1 :(得分: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++;
}
}