2

我有一个字符串列表,我想订购它们。

IEnumerable<String> strings = ...;
strings = strings.OrderBy(a => a);

我没有得到的是 lambda 表达式a => a的意义。首先我认为我可以像这样拉出一个属性并同时订购。

IEnumerable<Something> somethings = ...;
IEnumerable<String> strings = somethings.OrderBy(a => a.StringProperty);

但这不编译。所以我必须这样走。

IEnumerable<Something> somethings = ...;
IEnumerable<String> strings = somethings.Select(a
  => a.StringProperty).OrderBy(a => a);

那么为什么我必须在OrderBy命令中使用 lambda 表达式呢?!

4

5 回答 5

6

lambda 表示“您想要订购的东西”。

如果您选择一组人,并在他们的生日之前对其进行排序,那么您仍然有一组人——而不是一组生日;IE

IEnumerable<Person> people = ...;
IEnumerable<Person> sorted = people.OrderBy(a => a.DateOfBirth);

所以类似地,对一组Somethings排序StringProperty仍然会产生一组Somethings:

IEnumerable<Something> somethings = ...;
IEnumerable<Something> sorted = somethings.OrderBy(a => a.StringProperty);

在某些(极少数)情况下,您实际上的意思是“并按事物本身订购”。这通常仅适用于IEnumerable<string>或之类的事情IEnumerable<int>- 所以轻微的不便.OrderBy(x => x)是微不足道的。如果它困扰你,你总是可以编写一个扩展方法来隐藏这个细节。

于 2013-08-10T20:55:36.370 回答
2

当您订购一个集合时,它不会改变它的类型,因此

IEnumerable<Something> somethings = ...; 
var strings = somethings.OrderBy(a => a.StringProperty);

结果是IEnumerable<Something>,您必须选择属性来更改类型:

IEnumerable<String> strings = somethings
    .OrderBy(s => s.StringProperty)
    .Select(s => s.StringProperty);

那么为什么我必须在 OrderBy 命令中使用 lambda 表达式呢?!

因为Enumerable.OrderBy是一种需要参数的方法。

于 2013-08-10T20:54:26.800 回答
1

因为您没有选择它,所以您按它订购。

尝试这个:

Console.WriteLine(string.Join(", ",
    new[] { new { Int = 1 }, new { Int = 2 }, new { Int = 0 }
    .OrderBy(a => a.Int));

这将为您提供按Int酒店排序的列表,而不仅仅是随机排序!

这意味着您可以按对象的任何属性进行排序,而不仅仅是对象本身。

于 2013-08-10T20:54:35.037 回答
1

.OrderBy(TSource, TKey)方法的结构对 Source 项和要排序的项都有要求。lambda 表示“使用 TKey 订购 TSource”,或者在您的情况下是“使用 a 订购 A”

于 2013-08-10T20:58:08.107 回答
1

参数 lambda in 的目的OrderBy是准确地告诉用于排序的标准。它需要一个您正在排序的对象,并返回另一个将被排序的“事物”(相同或不同类型),有点像从原始源中提取要排序的键。

你的第一个样本真的很简单,你的咆哮在某种程度上是有道理的,因为如果你从一个字符串列表开始,你很可能想要精确地按这些字符串排序。这也让我想知道,为什么我们不能OrderBy为那些琐碎的情况使用无参数。

对于第二个片段:

IEnumerable<Something> somethings = ...;
IEnumerable<Something> strings = somethings.OrderBy(a => a.StringProperty);

这是“排序标准”有意义的时候,因为您通过从它们派生的某些属性值对对象进行排序,而不仅仅是对象本身(通常不可比较)。它不编译的原因是在第二个可枚举声明中,它应该是一个IEnumerable<Something>而不是IEnumerable<string>,因为排序将返回另一个与它收到的类型完全相同的列表,但顺序不同,而不管排序标准

在第三个片段中,您Select通过设置 string 属性来解决这个问题,这有效地产生了一个字符串列表,但是您在此过程中丢失了所有输入对象。lambda 参数在这里或多或少毫无意义且微不足道,因为您从一个普通字符串开始,与第一个示例完全相同。

另一种使用它的方法是指定一些不同的排序标准,而不是字符串的琐碎。假设您不想按字母顺序排序,而是按第三个字母排序:

IEnumerable<String> strings = ...;
strings = strings.OrderBy(a => a.Substring(2, 1));
于 2013-08-10T21:22:32.357 回答