按orderby对一个整型数组进行排序

26
我希望您能够将我的整型数组按升序排序。 首先,我复制了我的数组:
int[] copyArray = myArray.ToArray();

然后我想按升序对它进行排序,就像这样:

 int[] sortedCopy = from element in copyArray 
                    orderby element ascending select element;

但是我遇到了一个错误,“selected”被高亮显示,错误提示为:“无法隐式地将类型'System.Linq.IOrderedEnumerable'转换为'int[]'”。

你接下来要如何处理sortedCopy?也许你不需要一个数组。 - weston
3个回答

58
你需要在最后调用 ToArray() 来将有序序列转换成数组。LINQ 使用 延迟计算,这意味着在你调用 ToArray()ToList() 或其他类似方法之前,中间处理(在本例中为排序)不会执行。
这样做已经创建了元素的副本,因此你实际上不需要先创建自己的副本。
示例:
int[] sortedCopy = (from element in myArray orderby element ascending select element)
                   .ToArray();

最好使用表达式语法来编写:

int[] sortedCopy = myArray.OrderBy(i => i).ToArray();

1
非常感谢Jon先生! :)"(i => i)" 的意思是什么? - user1635406
9
i => i 是一个 lambda 函数;它描述了如何对数组进行排序。第一个 i 表示它接受一个名为 i 的参数(你可以选择任何合法的名称);这个参数是一个 int,因为这是数组包含的类型。第二部分是你想要按照什么排序。在这种情况下,我们希望将每个数字 "按其本身" 排序,所以使用 i => i。Marc 的回答中的 x => x.Name 意味着 "给定每个元素 x,按 x.Name 进行排序"。 - Jon
如果您首先转换为数组,然后再进行排序,处理速度会更快,不是吗? - Neville Nazerane
@NevilleNazerane:不会。此外,直觉在性能方面是一个糟糕的建议者,但如果有什么的话,我的直觉是ToArray() 先执行会更慢。 - Jon
好的,我原本以为myArray变量是一个列表。应该注意到它的名称。 - Neville Nazerane

27

注意:如果你不需要一个副本(即改变 myArray 是可以接受的),那么一个更简单、更高效的方法就是:

Array.Sort(myArray);

这个操作在原位对数组进行排序,在尽可能高效的情况下利用了其为数组的性质。

对于更复杂的场景(例如对象数组的按成员排序),可以像下面这样操作:

Array.Sort(entityArray, (x,y) => string.Compare(x.Name, y.Name));

这相当于道德等价物:

var sortedCopy = entityArray.OrderBy(x => x.Name).ToArray();

但是需要再次强调:进行原地排序。


1
谢谢,但这次我需要一份副本。不过很有趣的阅读。 :) - user1635406

3

我们不知道您接下来要做什么,但也许您并不需要一个数组。如果它将进入另一个linq语句或foreach循环中,那么只需保持原样即可,最简单的方法是使用var

var sortedCopy = myArray.OrderBy(i => i);

foreach(var item in sortedCopy)
{
   //print out for example
}

这使得linq尽可能地懒惰。如果你总是强制使用ToArrayToList,那么它就不得不立即评估并分配结果的内存。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接