这些问题询问如何通过单个索引对数组进行排序。正如其他人所展示的那样,我选择提供一个通用的解决方案来解决平局问题。
代码
def sort_by_index(arr, *idx_order)
arr.sort_by { |a| a.values_at(*idx_order) }
end
示例
arr = [["cart", "disk", "halt", "walk"],
["prot", "waco", "beau", "drab"],
["meet", "disk", "seem", "beam"],
["find", "asks", "noun", "keen"],
["jive", "disk", "look", "beam"]]
请注意,arr 与 OP 示例中给出的数组不同。
按索引 1 排序
sort_by_index(arr, 1)
#=> [["find", "asks", "noun", "keen"],
# ["cart", "disk", "halt", "walk"],
# ["meet", "disk", "seem", "beam"],
# ["jive", "disk", "look", "beam"],
# ["prot", "waco", "beau", "drab"]]
按索引 1 排序,与索引 3 断绝关系
sort_by_index(arr, 1, 3)
#=> [["find", "asks", "noun", "keen"],
# ["meet", "disk", "seem", "beam"],
# ["jive", "disk", "look", "beam"],
# ["cart", "disk", "halt", "walk"],
# ["prot", "waco", "beau", "drab"]]
按索引 1 排序,与索引 3 断开关联,将前两个索引与索引 2 断开关联
sort_by_index(arr, 1, 3, 2)
#=> [["find", "asks", "noun", "keen"],
# ["jive", "disk", "look", "beam"],
# ["meet", "disk", "seem", "beam"],
# ["cart", "disk", "halt", "walk"],
# ["prot", "waco", "beau", "drab"]]
说明
考虑第二个例子,idx_order = [1, 3]。然后,在排序时,arr 的元素 a ("rows") 被比较
a.values_at(*idx_order) #=> a.values_at(1, 3)
比较arr的前两个元素(arr[0]和arr[1])时,确定以下两个数组的顺序:
["cart","disk","halt","walk"].values_at(1, 3) #=> ["disk", "walk"]
["prot","waco","beau","drab"].values_at(1, 3) #=> ["waco", "drab"]
Array#<=> 方法用于确定这两个 2 元素数组的顺序。 (特别是文档的第三段,它解释了如何“逐元素”比较数组。)
自从
"disk" <=> "waco" #=> -1
arr[0] 在排序顺序中位于arr[1] 之前。
现在假设我们比较 arr[0] 和 arr[2]:
["cart","disk","halt","walk"].values_at(1, 3) #=> ["disk", "walk"]
["meet","disk","seem","beam"].values_at(1, 3) #=> ["disk", "beam"]
由于这两个 2 元素数组在索引 0 处都有 "disk",因此我们必须比较 "walk" 和 "beam" 以确定决胜局:
["disk", "walk"] <=> ["disk", "beam"] #=> 1
这告诉我们arr[2] 在排序顺序中位于arr[0] 之前。