我对 Ruby 相当陌生,我正在尝试实现以下目标:我有一个具有两个属性(refers_to
和 is
)的对象数组,它们是已经按日期排序了。最重要的是,我想对它们进行排序,例如
obj1 < obj2 if obj1.refers_to == obj2.is
这是我到目前为止所尝试过的,但是:
- 我很喜欢这样,这不是“Ruby”的做法。
它甚至不起作用:错误
未定义的方法
sort_by' for #<`(我认为我可能与枚举时的变异有关)@array.each_with_index do |e,i| if e.refers_to != 0 @array.slice(i+1,@array.count-i-1).each_with_index do |f,j| if f.is == e.refers_to #@array.insert( ... ) Insert doesn't work end end end end
更新:Majioa 的回答
虽然我从这个答案中学到了很多东西,并且虽然它在摆弄小数据集时起作用,但我现在意识到它不是,并且我开始认为这个结果不能通过(二进制)排序算法获得。
我的代数是无序的,所以我将缺乏适当的形式主义,但基本上排序算法所做的是两两比较元素并相应地移动它们。
让我们使用这个例子:
4, refers_to =>2
3
2
1
当我们达到这种状态时:
3,
2,
4,refers_to =>2
1
此时,我们需要这样说:如果 4 在正确的位置,请不要进一步移动它
,即在比较“4”与“1”时,我们需要要知道“2”的状态,因此我的假设是:
这无法通过二元排序来实现。
- 我说得有道理吗?
- 我们可以进行三级排序吗?
最佳答案
我想你应该这样做:
sorted = arr.sort do | obj1, obj2 |
obj1.date < obj2.date && -1 ||
obj1.date > obj2.date && 1 ||
obj1.refers_to == obj2.is && -1 || 0
end
它首先按日期对数组进行排序,当日期相等时,按条件排序。当比较结果为-1
时, obj1
已放在obj2
之前,如果1
反之亦然。
更新
假设我们有根据您的示例形成的数组:
l = [ [ 1, nil ], [ 2, nil ], [ 3, nil ], [ 4, 2 ] ]
让我们按升序排序:
l.sort do | x, y |
y[ 1 ] && x[ 0 ] <=> y[ 1 ] || x[ 0 ] <=> y[ 0 ]
end
# => [[1, nil], [2, nil], [4, 2], [3, nil]]
或者让我们按降序对其进行排序,但保持数字及其引用的顺序相同:
l.sort do | x, y |
y[ 1 ] && y[ 1 ] <=> x[ 0 ] || y[ 0 ] <=> x[ 0 ]
end
# => [[3, nil], [2, nil], [4, 2], [1, nil]]
关于ruby - Ruby 中的数组排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21052257/