在下面的代码中,我遗漏了编译器如何知道k映射到musos,以及为什么v是自动递增:
string[] musos = { "David Gilmour", "Rick Wright", "Roger Waters", "Nick Mason" };
int[] keys = new int[] { 1, 4, 3, 2 };
var sorted = musos.Select((k, v) => new { Value = k, Key = keys[v] })
.OrderBy(k => k.Key)
.Select(v => v.Value.Split().Last())
foreach (var item in sorted)
{
Console.WriteLine(item);
}
代码完美无缺,返回:
Gilmour Mason Waters Wright
答案 0 :(得分:2)
好吧,我们转到msdn
public static IEnumerable<TResult> Select<TSource, TResult>(
this IEnumerable<TSource> source,
Func<TSource, int, TResult> selector
)
通过合并将序列的每个元素投影到新表单中 元素的索引。
所以在你选择的时候,你得到了元素(k)及其索引(v)。
所以
你的代码有效,因为keys数组至少和musos数组一样长,所以
keys[0] = 1 // 0 = v
keys[1] = 4 // 1 = v
keys[2] = 3 // 2 = v
keys[3] = 2 // 3 = v
答案 1 :(得分:1)
因为在这种情况下,Select接受一个Func委托,它将IEnumerable的每个元素作为键传递给它,以及元素在枚举中的位置。在你的情况下,元素是来自musos数组的字符串。
以下代码:
string[] musos = { "David Gilmour", "Rick Wright", "Roger Waters", "Nick Mason" };
int[] keys = new int[] { 1, 4, 3, 2 };
musos.Select((k, v) => new { Value = k, Key = keys[v] })
可以解释为:
musos.Select((Func<string, int, ANONYMOUS_TYPE>)delegate(string k, int v){
return new ANONYMOUS_TYPE() { Value = k, Key = keys[v] };
});
上面,ANONYMOUS_TYPE
类型只是编译器自动生成的匿名类型的占位符,用于表示和保存lambda表达式返回的具有两个公共属性的对象:Value
of键入string
类型的Key
和int
。此类型可能如下所示:
class ANONYMOUS_TYPE
{
public ANONYMOUS_TYPE()
{
}
public string Value { get; set; }
public int Key { get; set; }
}
现在您可以想象在这种情况下Select的实现:
IEnumerable<ANONYMOUS_TYPE> Select<string, ANONYMOUS_TYPE>(IEnumerable<string> musos, Func<string, int, ANONYMOUS_TYPE> selector)
{
int pos = 0;
var results = new List<ANONYMOUS_TYPE>();
foreach(string k in musos)
{
results.add(selector(k, pos));
pos++;
}
return (IEnumerable<ANONYMOUS_TYPE>)results;
}