/ / Як розділити масив Ruby на масиви неоднакового розміру, використовуючи роздільник - масиви, ruby

Як розділити рубіновий масив на subarrays неоднакового розміру за допомогою делімітатора - масиви, рубіна

У мене є наступний масив:

arr = [0, 1, 1, 2, 3, 1, 0, 0, 1]

Не змінюючи порядку значень, мені потрібно підрозділити arr на менші масиви при кожному виникненні 0, таким, що результат буде:

arr = [ [0, 1, 1, 2, 3, 1], [0], [0, 1] ]

Якщо arr були струною, яку я міг би використати .split("0") а потім додати роздільник до кожного підмножина. Що було б найефективнішим еквівалентом .split() у звичайному Ruby для масивів?

Відповіді:

4 для відповіді № 1

Enumerable#slice_before робить це точно:

arr = [0, 1, 1, 2, 3, 1, 0, 0, 1]
p arr.slice_before(0).to_a
# => [[0, 1, 1, 2, 3, 1], [0], [0, 1]]

Дивіться це на repl.it: https://repl.it/FBhg


0 для відповіді № 2

З тих пір ActiveSupport визначає метод розбиття масиву # в Ruby, ми можемо використовувати його як вихідну точку:

class Array
def split(value = nil)
arr = dup
result = []
if block_given?
while (idx = arr.index { |i| yield i })
result << arr.shift(idx)
arr.shift
end
else
while (idx = arr.index(value))
result << arr.shift(idx)
arr.shift
end
end
result << arr
end
end

# then, using the above to achieve your goal:
arr = [0, 1, 1, 2, 3, 1, 0, 0, 1]
arr.split(0).map { |sub| sub.unshift(0) }
# => [[0], [0, 1, 1, 2, 3, 1], [0], [0, 1]]

Зауважте, що ваше словесне фразування алгоритму (розділення та подання) - це те, що відбувається тут, але очікуваний вихід відрізняється (є додатковий нуль через спосіб split робіт).

Ти хочеш розділити перед кожним нулем? Для цього ви могли б скористатися slice_before.

Ти хочеш розділити, але скинути порожні масиви? Це можна зробити швидко compact перед тим, як прикинутись, але ви втратите [0] підмагістраль.

Ти хочеш розділіть, але випустіть перший елемент, якщо порожній?

Ти хочеш розколотись на /0+/?