ruby 数组自定义排序_在Ruby中对数组排序

ruby 数组自定义排序

Sorting was a preoccupation for computer scientists from early on. There were many algorithms that came into and fell out of use and still today new algorithms are pushing the boundaries of performance. Being a high-level language, you won't be implementing sorting algorithms in Ruby if you care about performance, and besides, sorting Arrays and other collections are yet more things Ruby does for you.

从一开始,排序就成为计算机科学家的头等大事。 有很多算法进入使用和废弃状态,但是今天仍然有新算法在推动性能极限。 作为高级语言,如果您关心性能,则不会在Ruby中实现排序算法,此外,对数组和其他集合进行排序是Ruby为您提供的更多功能。

排序数组 ( Sorting Arrays )

Technically, sorting is a job handled by the Enumerable module. The Enumerable module is what ties all types of collections in Ruby together. It handles iterating over collections, sorting, looking through and finding certain elements, etc. How Enumerable sorts a collection is a bit of a mystery, or at least it should remain so. The actual sorting algorithm is irrelevant, the only thing you need to know is that objects in the collection are compared using the "spaceship operator."

从技术上讲,排序是由Enumerable模块处理的工作。 Enumerable模块将Ruby中的所有类型的集合联系在一起。 它处理对集合的迭代,排序,浏览和查找某些元素等。如何对集合进行Enumerable排序是一个谜,或者至少应该如此。 实际的排序算法是无关紧要的,您唯一需要知道的是使用“太空船运算符”比较集合中的对象。

在太空飞船中排序 ( Sorting in a Spaceship )

The "spaceship operator" takes two objects, compares them and then returns -1, 0 or 1. That's a bit vague, but the operator itself doesn't have a very well defined behavior. Let's take Numeric objects for example. If you have two numeric objects a and b, and evaluate a <=> b, what will the expression evaluate to? In the case of Numerics, it's easy to tell. If a is greater than b, it will be -1, if they're equal it will be 0 and if b is greater than a, it will be 1. This is used to tell the sorting algorithm which one of the two objects should go first in the array. Just remember that if the left-hand operand is to come first in the array, it should evaluate to -1, if the right hand should be first it should be 1, and if it doesn't matter it should be 0.

“太空飞船操作员”将两个对象进行比较,然后返回-1、0或1。这有点含糊,但是操作员本身并没有非常明确的行为。 让我们以数字对象为例。 如果您有两个数字对象ab ,并且计算a <=> b ,则表达式的计算结果是什么? 就数字而言,这很容易分辨。 如果a大于b,则将为-1,如果它们相等,则将为0,如果b大于a,则将为1。这用于告诉排序算法应两个对象中的哪个对象在数组中优先。 只需记住,如果左操作数要在数组中排在第一位,则其求值应为-1,如果右手应首先为1,则应为1,如果没关系,则应为0。

It doesn't always follow such tidy rules. What happens if you use this operator on two objects of different types? You'll probably get an exception. What happens when you call 1 <=> 'monkey'? This will be the equivalent of calling 1.<=>('monkey'), meaning the actual method is being called on the left operand and Fixnum#<=> returns nil if the right-hand operand is not a numeric. If the operator returns nil, the sort method will raise an exception. So, before sorting arrays make sure they contain objects that can be sorted.

它并不总是遵循这样整洁的规则。 如果对两个不同类型的对象使用此运算符,会发生什么情况? 您可能会得到一个例外。 当您调用1 <=>'monkey'时会发生什么? 这等效于调用1。<=>('monkey') ,这意味着实际的方法正在左侧操作数上调用,并且如果右侧操作数不是数字,则Fixnum#<=>返回nil。 如果运算符返回nil,则sort方法将引发异常。 因此,在对数组进行排序之前,请确保它们包含可以排序的对象。

Second, the actual behavior of the spaceship operator isn't defined. It's only defined for some of the base classes, and for your custom classes, it's totally up to you what you want them to mean. If you have a Student class you can have student sort by last name, first name, grade level or a combination of that. So always be aware that the behavior of the spaceship operator and sorting is not well defined for anything but the base types.

其次,未定义太空飞船操作员的实际行为。 它仅为某些基类定义,而对于自定义类,则完全由您决定它们的含义。 如果您有学生班,则可以让学生按姓氏,名字,年级或它们的组合排序。 因此,请始终注意,除了基本类型以外,对于其他任何东西,航天器操作员的行为和排序都没有很好地定义。

执行排序 ( Performing a Sort )

You have an Array of Numeric objects and you'd like to sort them. There are two primary methods to do this: sort and sort!. The first creates a copy of the array, sorts it and returns it. The second sorts the array in place.

您有一个数字对象数组,想要对它们进行排序。 有两种主要方法可以做到这一点: 排序排序! 。 第一个创建数组的副本,对其进行排序并返回它。 第二个对数组进行排序。

That's pretty self-explanatory. So let's take it up a notch. What if you don't want to rely on the spaceship operator? What if you want a completely different behavior? These two sorting methods take an optional block parameter. That block takes two parameters and should yield values just as the spaceship operator does: -1, 0 and 1. So, given an array, we want to sort it so all values that are divisible by 3 come first, and all others come after. The actual order doesn't matter here, just that those divisible by 3 come first.

这是不言自明的。 因此,让我们提高一个档次。 如果您不想依靠太空飞船操作员怎么办? 如果您想要完全不同的行为怎么办? 这两种排序方法采用可选的块参数。 该块需要两个参数,并且应像航天器运算符一样产生值:-1、0和1。因此,给定一个数组,我们希望对其进行排序,以便所有可被3整除的值排在第一位,所有其他值排在第二位。 实际顺序在这里无关紧要,只是那些可被3整除的数排在第一位。

How does this work? First, note the block argument to the sort method. Second, note the modulo divisions done on the block parameters, and the reuse of the spaceship operator. If one is a multiple of 3, the modulo will be 0, otherwise, it will be 1 or 2. Since 0 will sort before 1 or 2, only the modulo matters here. Using a block parameter is particularly useful in arrays that have more than one type of element, or when you want to sort on custom classes that don't have a defined spaceship operator.

这是如何运作的? 首先,请注意sort方法的block参数。 其次,请注意在块参数上完成的模除法,以及宇宙飞船运算符的重用。 如果1是3的倍数,则模数将为0,否则将为1或2。由于0将在1或2之前排序,因此这里只有模数重要。 在具有不止一种元素类型的数组中,或者要对没有定义的宇宙飞船运算符的自定义类进行排序时,使用块参数特别有用。

最后排序 ( One Last Sort )

There is one more sort method, called sort_by. However, you should first understand translating arrays and collections with map before tackling sort_by.

还有另一种排序方法,称为sort_by 。 但是,在处理sort_by之前,您应该首先了解如何使用map翻译数组和集合。

翻译自: https://www.thoughtco.com/sorting-arrays-2908238

ruby 数组自定义排序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值