IEnumerable<T> 上的延迟 OrderBy
Deferred OrderBy on IEnumerable<T>
我有这个代码,它只是根据每个整数中的数字对整数的 IEnumerable 进行排序。
var ints = new List<int>() { 66, 7, 9, -5, -22, 67, 122, -333, 555, -2 };
var ordered = ints.OrderBy(x =>
{
x = Math.Abs(x);
Console.WriteLine($"Getting length of {x}");
int len = 0;
while (x >= 1)
{
len++;
x /= 10;
}
return len;
});
Console.WriteLine("After OrderBy");
Console.WriteLine("Fetching first item in ordered sequence");
Console.WriteLine($"First item is {ordered.First()}");
Console.WriteLine(string.Join(" ", ordered));
因此,当程序在 ordered
序列中获取第一项时,IEnumerable 正在排序(我正在接收输出行 Getting lenght of XXX
),因为 OrderBy 被推迟了,那很清楚。
但是为什么当程序点击时 Console.WriteLine(string.Join(" ", ordered));
我又得到了这个输出? IEnumerable 是否再次排序? (不是已经排序了吗?)
当您将值赋给 ordered
时,它们实际上并没有排序。它基本上是订购清单的说明。 IOrderedEnumerable<int>
。因此,每次您尝试访问第一个项目或任何其他项目时,它都会将其转换为有序列表,以便为您提供该项目。第一次是你运行.First()
,第二次是你运行string.Join
.
在这两种情况下,程序都会创建一个有序列表的 2 个不同实例,用完它,然后通过丢失引用来处理它(因为你没有保存它)。
如果你需要Ordered只排序一次,你需要在它上面调用ToList(),在这种情况下你只会看到一次列表结果。既然订了。
var ints = new List<int>() { 66, 7, 9, -5, -22, 67, 122, -333, 555, -2 };
var ordered = ints.OrderBy(x =>
{
x = Math.Abs(x);
Console.WriteLine($"Getting length of {x}");
int len = 0;
while (x >= 1)
{
len++;
x /= 10;
}
return len;
}).ToList();
Console.WriteLine("After OrderBy");
Console.WriteLine("Fetching first item in ordered sequence");
Console.WriteLine($"First item is {ordered.First()}");
Console.WriteLine(string.Join(" ", ordered));
我有这个代码,它只是根据每个整数中的数字对整数的 IEnumerable 进行排序。
var ints = new List<int>() { 66, 7, 9, -5, -22, 67, 122, -333, 555, -2 };
var ordered = ints.OrderBy(x =>
{
x = Math.Abs(x);
Console.WriteLine($"Getting length of {x}");
int len = 0;
while (x >= 1)
{
len++;
x /= 10;
}
return len;
});
Console.WriteLine("After OrderBy");
Console.WriteLine("Fetching first item in ordered sequence");
Console.WriteLine($"First item is {ordered.First()}");
Console.WriteLine(string.Join(" ", ordered));
因此,当程序在 ordered
序列中获取第一项时,IEnumerable 正在排序(我正在接收输出行 Getting lenght of XXX
),因为 OrderBy 被推迟了,那很清楚。
但是为什么当程序点击时 Console.WriteLine(string.Join(" ", ordered));
我又得到了这个输出? IEnumerable 是否再次排序? (不是已经排序了吗?)
当您将值赋给 ordered
时,它们实际上并没有排序。它基本上是订购清单的说明。 IOrderedEnumerable<int>
。因此,每次您尝试访问第一个项目或任何其他项目时,它都会将其转换为有序列表,以便为您提供该项目。第一次是你运行.First()
,第二次是你运行string.Join
.
在这两种情况下,程序都会创建一个有序列表的 2 个不同实例,用完它,然后通过丢失引用来处理它(因为你没有保存它)。
如果你需要Ordered只排序一次,你需要在它上面调用ToList(),在这种情况下你只会看到一次列表结果。既然订了。
var ints = new List<int>() { 66, 7, 9, -5, -22, 67, 122, -333, 555, -2 };
var ordered = ints.OrderBy(x =>
{
x = Math.Abs(x);
Console.WriteLine($"Getting length of {x}");
int len = 0;
while (x >= 1)
{
len++;
x /= 10;
}
return len;
}).ToList();
Console.WriteLine("After OrderBy");
Console.WriteLine("Fetching first item in ordered sequence");
Console.WriteLine($"First item is {ordered.First()}");
Console.WriteLine(string.Join(" ", ordered));