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

Lyr*_*res -2 ruby arrays sorting

我有一个数组数组:

arr_of_arrs = [
  ["cart", "disk", "halt", "walk"],
  ["prot", "waco", "beau", "drab"],
  ["meet", "lick", "look", "itch"],
  ["find", "asks", "noun", "keen"],
  ["jive", "moon", "seem", "beam"]
]
Run Code Online (Sandbox Code Playgroud)

我怎么能按照子阵列的指定索引处的元素的字母顺序排序这个数组数组,比如索引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
Run Code Online (Sandbox Code Playgroud)

saw*_*awa 6

如果索引是3,那么:

arr_of_arrs.sort_by{|a| a[3]}
Run Code Online (Sandbox Code Playgroud)


Car*_*and 5

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

代码

def sort_by_index(arr, *idx_order)
  arr.sort_by { |a| a.values_at(*idx_order) }
end
Run Code Online (Sandbox Code Playgroud)

例子

arr = [["cart", "disk", "halt", "walk"],
       ["prot", "waco", "beau", "drab"],
       ["meet", "disk", "seem", "beam"],
       ["find", "asks", "noun", "keen"],
       ["jive", "disk", "look", "beam"]]
Run Code Online (Sandbox Code Playgroud)

请注意,这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"]]
Run Code Online (Sandbox Code Playgroud)

按索引 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"]]
Run Code Online (Sandbox Code Playgroud)

按索引 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"]]
Run Code Online (Sandbox Code Playgroud)

解释

考虑第二个例子,其中idx_order = [1, 3]. 然后,在排序时,元素a(“行”)arr通过以下方式进行比较

a.values_at(*idx_order) #=> a.values_at(1, 3)
Run Code Online (Sandbox Code Playgroud)

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"]
Run Code Online (Sandbox Code Playgroud)

Array#<=>方法用于确定这两个 2 元素数组的顺序。(特别请参阅文档的第三段,其中解释了如何“按元素”比较数组。)

自从

"disk" <=> "waco" #=> -1
Run Code Online (Sandbox Code Playgroud)

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"]
Run Code Online (Sandbox Code Playgroud)

由于这两个 2 元素数组都有"disk"at 索引0,我们必须比较"walk""beam"确定决胜局:

["disk", "walk"] <=> ["disk", "beam"] #=> 1
Run Code Online (Sandbox Code Playgroud)

这告诉我们排序顺序在arr[2]前面。arr[0]