Ruby сортирует массив массивов по субиндексам по алфавиту - PullRequest
0 голосов
/ 05 июня 2018

У меня есть массив массивов:

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 голосов
/ 05 июня 2018

Сортировка по четвертому элементу (т.е. по индексу 3):

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

или:

index = ->(i) { ->(a) { a[i] } }
arr_of_arrs.sort_by(&index[3])
0 голосов
/ 05 июня 2018

В вопросах спрашивается, как можно сортировать массивы по одному индексу.Поскольку другие показали, как это можно сделать, я решил предоставить обобщенное решение, которое решает проблему разрыва связей.

Код

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)

При сравнении первых двух элементов 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 # <=> используется для определения порядка этих двухэлементных массивов.(См., В частности, третий абзац документа, в котором объясняется, как массивы сравниваются «поэлементно».)

Так как

"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"]

Поскольку оба этих двухэлементных массива имеют "disk" по индексу 0, мы должны сравнить "walk" и "beam", чтобы определить прерыватель:

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

, который говорит нам, что arr[2] предшествует arr[0] в порядке сортировки.

0 голосов
/ 05 июня 2018

Если индекс 3, то:

arr_of_arrs.sort_by{|a| a[3]}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...