У мене є наступний масив:
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 для відповіді № 1Enumerable#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+/
?