简体   繁体   English

OrderBy中lambda表达式的重点是什么?

[英]What's the point of lambda expression in OrderBy?

I have a list of strings and I'd like to order them. 我有一个字符串列表,我想订购它们。

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

What I don't get is the point of the lambda expression a => a in there. 我没有得到的是lambda表达式a => a的重点。 First I thought that I can pull out a property and order at the same like like this. 首先,我认为我可以像这样拿出一个房产和订单。

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

But that doesn't compile. 但那不编译。 So I'll have to go like this. 所以我必须这样做。

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

So why am I enforced to use the lambda expression in the OrderBy command?! 那么为什么我强制要在OrderBy命令中使用lambda表达式?!

The lambda indicates the "what you want to order by". lambda表示“你想要订购什么”。

If you take a set of people, and order them by their birthday, you still have a set of people - not a set of birthdays; 如果你带一群人,并在他们的生日订购,你仍然有一组人 - 而不是一组生日; ie

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

so similarly, ordering a set of Something s by StringProperty still results in a set of Something s: 所以类似地,通过StringProperty排序一组Something仍然会产生一组Something s:

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

In some (very few) cases, you do actually mean "and order it by the thing itself". 在一些(很少)的情况下,你实际上意味着“并通过事物本身对其进行排序”。 This usually applies only to things like IEnumerable<string> or IEnumerable<int> - so the minor inconvenience of .OrderBy(x => x) is trivial. 这通常仅适用于IEnumerable<string>IEnumerable<int> - 因此.OrderBy(x => x)的轻微不便是微不足道的。 If it bothers you, you could always write an extension method to hide this detail. 如果它困扰你,你总是可以写一个扩展方法来隐藏这个细节。

When you order a collection it doesn't change it's type, hence 当您订购一个集合时,它不会改变它的类型

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

results in an IEnumerable<Something> , you have to select the property to change the type: 导致IEnumerable<Something> ,你必须选择属性来改变类型:

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

So why am I enforced to use the lambda expression in the OrderBy command?! 那么为什么我强制要在OrderBy命令中使用lambda表达式?!

Because Enumerable.OrderBy is a method that needs an argument. 因为Enumerable.OrderBy是一个需要参数的方法。

Because you're not selecting it, you're ordering by it. 因为您没有选择它,所以您可以通过它进行订购。

Try this: 尝试这个:

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

This will give you the lists, ordered by the Int property, not just randomly ordered! 这将为您提供由Int属性排序的列表,而不仅仅是随机排序!

This means that you can order by any property of the object, instead of just the object itself. 这意味着您可以按对象的任何属性进行排序,而不仅仅是对象本身。

the structure of the .OrderBy(TSource, TKey) method has a requirement for both the Source item and the item to sort by. .OrderBy(TSource, TKey)方法的结构要求Source项和要排序的项。 the lambda is saying "Order TSource using TKey", or in your case, "Order a using a" lambda说“使用TKey订购TSource”,或者在你的情况下,“订购a使用”

The purpose of the parameter lambda in OrderBy is precisely tell the criteria using for ordering. OrderBy参数lambda的目的是准确地告诉用于排序的标准。 It takes an object you're sorting, and returns another "thing" (same type or not) which will be sorted, sort of extracting a key to be sorted from the original source. 它需要一个你正在排序的对象,并返回另一个将被排序的“东西”(相同或不相同的类型),排序提取要从原始源排序的密钥。

Your first sample is really trivial, and your rant is somewhat justified there, since if you start from a list of strings, you most likely will want to sort by those strings precisely. 你的第一个样本非常简单,你的咆哮在某种程度上是合理的,因为如果你从一个字符串列表开始,你很可能会想要精确地按这些字符串排序。 Which makes me wonder too, why we can't have a parameterless OrderBy for those trivial cases. 这让我也很奇怪,为什么我们不能为那些微不足道的案例设置无参数的OrderBy

For the second snippet: 对于第二个片段:

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

Here is when the "sorting criteria" makes sense, as you order the objects by some property value derived from them, and not just for the objects themselves (which generally aren't comparable). 这是“排序标准”有意义的时候,因为您通过从它们派生的某个属性值来对对象进行排序,而不仅仅是对象本身(通常不具有可比性)。 The reason it doesn't compiles is in the second enumerable declaration, it should be an IEnumerable<Something> instead of IEnumerable<string> , because the ordering will return another list of the very same type as it received, but in a different order, regardless of sorting criteria . 它不编译的原因是在第二个可枚举声明中,它应该是一个IEnumerable<Something>而不是IEnumerable<string> ,因为排序将返回另一个与它收到的类型相同的列表,但顺序不同, 无论排序标准如何

In the third snippet, you solve that by Select ing the string property, that effectively yields a list of strings, but you lose all the input objects in the process. 在第三个片段中,您可以通过Select字符串属性来解决这个问题,这会有效地生成字符串列表,但是会丢失进程中的所有输入对象。 The lambda parameter is more or less pointless and trivial here, as you're starting from a plain string to begin with, the very same as the first sample. lambda参数在这里或多或少是毫无意义的,因为你从一个普通的字符串开始,与第一个样本完全相同。

Another way to use it would be to specify some different sorting criteria other than the trivial for strings. 另一种使用它的方法是指定一些不同的排序标准,而不是字符串。 Say you want to sort not alphabetically, but by the third letter instead: 假设您不是按字母顺序排序,而是按第三个字母排序:

IEnumerable<String> strings = ...;
strings = strings.OrderBy(a => a.Substring(2, 1));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM