有人可以告诉我如何根据自定义字符串对嵌套数组进行排序吗?例如,有没有办法排序:
[['Red','Blue'],['Green','Orange'],['Purple','Yellow']]
"Orange"
,"Yellow"
,然后是"Blue"
?最终结果如下:
[['Green','Orange'],['Purple','Yellow'],['Red','Blue']]
它没有按字母顺序排序。我很想知道我是否可以定义值来排序以实现上述目标。
答案 0 :(得分:8)
sort_by
对于这种排序总是非常方便:
a = [['Red','Blue'],['Green','Orange'],['Purple','Yellow']]
order_array = ['Orange', 'Yellow', 'Blue']
p a.sort_by { |arr| order_array.index(arr[1]) }
# => [["Green", "Orange"], ["Purple", "Yellow"], ["Red", "Blue"]]
答案 1 :(得分:3)
ORDER = %w[Orange Yellow Blue]
ary = [['Red','Blue'],['Green','Orange'],['Purple','Yellow']]
ary.group_by{ |a| a.last }.values_at(*ORDER)
# => [[["Green", "Orange"]], [["Purple", "Yellow"]], [["Red", "Blue"]]]
以下是group_by
为聚会带来的内容:
ary.group_by{ |a| a.last }
# => {"Blue"=>[["Red", "Blue"]],
# "Orange"=>[["Green", "Orange"]],
# "Yellow"=>[["Purple", "Yellow"]]}
获得用于对每个数组进行分组的值的哈希后,values_at
可以很容易地按正确的顺序提取它们。
这是一种非常快速有效的方法来完成任务,因为随着ary
的增长,它几乎没有变慢,因为没有真正的排序,它只是按值分组,然后提取来自给定顺序的哈希。
如果您想要与示例中完全相同的数组数组,flatten
结果一次:
ary.group_by{ |a| a.last }.values_at(*ORDER).flatten(1)
# => [["Green", "Orange"], ["Purple", "Yellow"], ["Red", "Blue"]]
如果要有多个“橙色”,“黄色”或“蓝色”元素,您将不希望这样做,因为结果将不会非常有用。
答案 2 :(得分:2)
您可以在集合上调用.sort
,并传递一个知道如何判断一个元素是否大于另一个元素的块。
如果您只想使用有序的字符串列表来确定哪个字符串比另一个更大,那么您可以定义一个简单的比较器,它使用排序列表中每个字符串的索引来确定哪个更大。
strs = [['Red','Blue'],['Green','Orange'],['Purple','Yellow']]
ordering = %w(Orange Yellow Blue)
p strs.sort { |a,b| ordering.index(a[1]) <=> ordering.index(b[1]) }
# [["Green", "Orange"], ["Purple", "Yellow"], ["Red", "Blue"]]
答案 3 :(得分:0)
这是一种允许“橙色”,“黄色”和“蓝色”位于每个阵列中的任何位置的方法,并且每个阵列可以不包含这三种颜色中的一些或全部。使用给定的字符串排序对每个数组以及包含的数组进行排序。正常数组排序适用,因此如果两个数组中每个数组的第一个元素相同,则比较第二个元素等。
我暂时重新定义String#<=>,然后按常规方式排序,然后在返回前恢复String#<=>
。
<强>代码强>
def reorder(arr)
String.send(:alias_method, :old_compare, :<=>)
String.class_eval do
define_method(:<=>) do |other|
order = ["Blue", "Yellow", "Orange"] # increasing priority
self_ndx = order.index(self) || -1
other_ndx = order.index(other) || -1
other_ndx <=> self_ndx
end
end
a = arr.map(&:sort).sort
String.send(:alias_method, :<=>, :old_compare )
String.send(:undef_method, :old_compare)
a
end
<强>实施例强>
reorder [["Red", "Blue"], ["Green", "Orange"], ["Purple", "Yellow"]]
#=> [["Orange", "Green"], ["Yellow", "Purple"], ["Blue", "Red"]]
reorder [["Blue", "Orange"], ["Purple", "Green"], ["Purple", "Orange"]]
#=> [["Orange", "Blue"], ["Orange", "Purple"], ["Purple", "Green"]]
reorder [["Yellow", "Orange"], ["Orange", "Orange"], ["Blue", "Yellow"]]
#=> [["Orange", "Orange"], ["Orange", "Yellow"], ["Yellow", "Blue"]]
reorder [["Yellow", "Purple"], ["Purple", "Orange", "Blue"], ["Blue", "Yellow"]]
#=> [["Orange", "Blue", "Purple"], ["Yellow", "Blue"], ["Yellow", "Purple"]]