如何计算 IEnumerable并将其存储在 T 类型中
本文关键字:存储 类型 的秩 计算 IEnumerable 何计算 | 更新日期: 2023-09-27 18:32:37
我想计算IEnumerable列表中元素的排名并将其分配给成员。但是下面的代码仅在第一次调用时才有效。第二次调用从上次排名值开始。所以不是输出 012 和 012,而是 012 和 345
class MyClass
{
public string Name { get; set; }
public int Rank { get; set; }
}
public void SecondTimeRankEvaluvate()
{
MyClass[] myArray = new MyClass[]
{
new MyClass() { Name = "Foo" },
new MyClass() { Name = "Bar" },
new MyClass() { Name = "Baz" }
};
int r = 0;
var first = myArray.Select(s => { s.Rank = r++; return s; });
foreach (var item in first)
{
Console.Write(item.Rank);
}
// Prints 012
Console.WriteLine("");
foreach (var item in first)
{
Console.Write(item.Rank);
}
// Prints 345
}
我知道变量r
正在被捕获(闭包)并在第二次调用时重复使用。我不希望这种行为。有没有干净的方法来计算等级并分配它?此外r
变量(在实际代码中)不在存在循环foreach
同一范围内。它位于一个返回var first
<</p>
var first = myArray.Select((s, i) => { s.Rank = i; return s; });
LINQ 使用惰性求值,并在每次使用 myArray
时运行 Select
部分。
通过将结果存储在 List
中,可以强制仅执行一次评估。
改变
var first = myArray.Select(s => { s.Rank = r++; return s; });
自
var first = myArray.Select(s => { s.Rank = r++; return s; }).ToList();
另一种方法是每次都使用 Zip
将myArray
与新序列连接起来,如下所示
var first = myArray.Zip(Enumerable.Range(0, int.MaxValue), (s, r) =>
{
s.Rank = r;
return s;
});
如果不查询集合,则不应使用 LINQ。
要更新数组中的每个项目,请使用for
循环:
for (int i = 0; i < myArray.Length; i++)
{
myArray[i].Rank = i;
}
若要更新可枚举项中的每个项,请使用foreach
循环:
int r = 0;
foreach (var item in myArray)
{
item.Rank = r++;
}