Как сгруппировать элементы массива по индексу? - PullRequest
4 голосов
/ 24 апреля 2020

У меня есть массив arr, который я хочу сгруппировать по индексам, указанным в массиве idx. Я имею в виду, что подмассив

  • 1 будет заканчиваться индексом 1
  • подмассив 2 будет заканчиваться индексом 5
  • подмассив 3 будет заканчиваться индексом 7
  • Подмассив N будет сформирован из элемента с индексом 8 до последнего элемента arr

С моим текущим кодом я могу сгруппировать первый подмассив с первым индексом idx idx [0] = 1.

Тогда, как реплицировать все индексы в массиве idx? Заранее спасибо.

Мой текущий код и выходные данные таковы:

idx = [1,5,7]
arr = ['a','b','c','d','e','f','g','h','i','j','k']

arr.group_by.with_index { |z, i| i <= idx[0] }.values
=> [["a", "b"], ["c", "d", "e", "f", "g", "h", "i", "j", "k"]]

и мой желаемый вывод выглядит так:

output   --> [["a", "b"], ["c", "d", "e", "f"], ["g", "h"], ["i", "j", "k"]]

#Indexes -->    0    1      2    3    4    5      6    7      8    9    10  

Ответы [ 3 ]

5 голосов
/ 24 апреля 2020

Вы можете использовать slice_after, чтобы разрезать массив после каждого элемента, индекс которого находится в idx:

idx = [1, 5, 7]
arr = %w[a b c d e f g h i j k]

arr.enum_for(:slice_after).with_index { |_, i| idx.include?(i) }.to_a
#=> [["a", "b"], ["c", "d", "e", "f"], ["g", "h"], ["i", "j", "k"]]

То, что enum_for (к сожалению) необходимо для цепочки slice_after и with_index.

1 голос
/ 24 апреля 2020
arr = [9, 3, 1, 6, 2, 4, 0, 1, 5, 8] 
end_idx = [1, 5, 7]

[-1, *end_idx, arr.size-1].uniq.each_cons(2).
  map { |s,e| arr.values_at(s+1..e) }
  #=> [[9, 3], [1, 6, 2, 4], [0, 1], [5, 8]]  

Шаги следующие:

a = [-1, *end_idx, arr.size-1]
  #=> [-1, 1, 5, 7, 9]
b = a.uniq
  #=> [-1, 1, 5, 9]
c = b.each_cons(2)
  #=> #<Enumerator: [-1, 1, 5, 7, 9]:each_cons(2)> 
c.map { |s,e| arr.values_at(s+1..e) }
  #=> [[9, 3], [1, 6, 2, 4], [0, 1], [5, 8]] 

Можно увидеть элементы, сгенерированные и переданные в map перечислитель c путем преобразования c в массив.

c.to_a
  #=> [[-1, 1], [1, 5], [5, 7], [7, 9]] 

См. Array # values_at .

1 голос
/ 24 апреля 2020

Другое решение

idx = [1, 5, 7]
arr = ['a','b','c','d','e','f','g','h','i','j','k']
from = 0

arr.map.with_index { |a, i|  
  if idx.include?(i)
    result = arr[from..i]  
    from = i + 1 
  end
  result
}.compact

 => [["a", "b"], ["c", "d", "e", "f"], ["g", "h"]] 
...