Ruby按字母顺序按子索引排序数组

时间:2018-06-05 04:45:45

标签: arrays ruby sorting

我有一个数组数组:

arr_of_arrs = [
  ["cart", "disk", "halt", "walk"],
  ["prot", "waco", "beau", "drab"],
  ["meet", "lick", "look", "itch"],
  ["find", "asks", "noun", "keen"],
  ["jive", "moon", "seem", "beam"]
]

我怎么能按照子阵列的指定索引处的元素的字母顺序排序这个数组数组,比如索引3,所以它的新顺序是:

[
  ["jive", "moon", "seem", "beam"],
  ["prot", "waco", "beau", "drab"],
  ["meet", "lick", "look", "itch"],
  ["find", "asks", "noun", "keen"],
  ["cart", "disk", "halt", "walk"]
] #                        ^^^^^^ index 3 is ordered

3 个答案:

答案 0 :(得分:6)

If the index is 3, then:

arr_of_arrs.sort_by{|a| a[3]}

答案 1 :(得分:4)

问题询问如何通过单个索引对数组进行排序。正如其他人已经展示了如何做到这一点,我选择提供一个解决打破平局的通用解决方案。

<强>代码

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]。然后,在排序时,a的元素arr(“行”)将通过

进行比较
a.values_at(*idx_order) #=> a.values_at(1, 3)

比较arrarr[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
发现{p> 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元素数组都在"disk"处有0,我们必须比较"walk""beam"来确定决胜局:

["disk", "walk"] <=> ["disk", "beam"] #=> 1

告诉我们arr[2]在排序顺序中位于arr[0]之前。

答案 2 :(得分:2)

To sort by the fourth element (i.e. index 3):

arr_of_arrs.sort_by { |a| a[3] }

or:

index = ->(i) { ->(a) { a[i] } }
arr_of_arrs.sort_by(&index[3])