我需要連續號碼添加到新陣列,如果它是不連續的號碼,只值添加到一個新的數組:連續的分組編號在數組
old_array = [1, 2, 3, 5, 7, 8, 9, 20, 21, 23, 29]
我想這結果:
new_array = [
[1,2,3],
[5],
[7,8,9]
[20,21]
[23],
[29]
]
是否有更簡單的方法來做到這一點
我需要連續號碼添加到新陣列,如果它是不連續的號碼,只值添加到一個新的數組:連續的分組編號在數組
old_array = [1, 2, 3, 5, 7, 8, 9, 20, 21, 23, 29]
我想這結果:
new_array = [
[1,2,3],
[5],
[7,8,9]
[20,21]
[23],
[29]
]
是否有更簡單的方法來做到這一點
這是RDoc給出(略有修改),官方的回答:
種actual = old_array.first
old_array.slice_before do
|e|
expected, actual = actual.next, e
expected != actual
end.to_a
如何在ruby 1.8.7中編寫代碼? – bluexuemei
Ruby 1.8.7不再被維護,並且包含幾個已知的安全漏洞。你應該避免使用它。 –
很好的答案,謝謝 – bluexuemei
一對夫婦的其他方式:
old_array = [1, 2, 3, 5, 7, 8, 9, 20, 21, 23, 29]
#1
a, b = [], []
enum = old_array.each
loop do
b << enum.next
unless enum.peek.eql?(b.last.succ)
a << b
b = []
end
end
a << b if b.any?
a #=> [[1, 2, 3], [5], [7, 8, 9], [20, 21], [23], [29]]
#2
def pull_range(arr)
b = arr.take_while.with_index { |e,i| e-i == arr.first }
[b, arr[b.size..-1]]
end
b, l = [], a
while l.any?
f, l = pull_range(l)
b << f
end
b #=> [[1, 2, 3], [5], [7, 8, 9], [20, 21], [23], [29]]
可能不應該這樣說,但那先生是一件藝術品! –
感謝恭維,@約翰。 (約翰指的是#1;後來我加了#2)。 –
你也可以做這樣的:
old_array=[1, 2, 3, 5, 7, 8, 9, 20, 21, 23, 29]
new_array=[]
tmp=[]
prev=nil
for i in old_array.each
if i != old_array[0]
if i - prev == 1
tmp << i
else
new_array << tmp
tmp=[i]
end
if i == old_array[-1]
new_array << tmp
break
end
prev=i
else
prev=i
tmp << i
end
end
使用chunk
你可以這樣做:
old_array.chunk([old_array[0],old_array[0]]) do |item, block_data|
if item > block_data[1]+1
block_data[0] = item
end
block_data[1] = item
block_data[0]
end.map { |_, i| i }
# => [[1, 2, 3], [5], [7, 8, 9], [20, 21], [23], [29]]
一些答案似乎不必要的長時間,就可以做到這一點非常緊湊的方式:
arr = [1, 2, 3, 5, 7, 8, 9, 20, 21, 23, 29]
arr.inject([]) { |a,e| (a[-1] && e == a[-1][-1] + 1) ? a[-1] << e : a << [e]; a }
# [[1, 2, 3], [5], [7, 8, 9], [20, 21], [23], [29]]
另外,先從第一個元素,以擺脫a[-1]
條件(需要的情況下,當a[-1]
將nil
,因爲a
是空的):
arr[1..-1].inject([[arr[0]]]) { |a,e| e == a[-1][-1] + 1 ? a[-1] << e : a << [e]; a }
# [[1, 2, 3], [5], [7, 8, 9], [20, 21], [23], [29]]
Enumerable#inject迭代可枚舉的所有元素,建立其與給定的對象開始的結果值。我在我的解決方案中分別給它一個空數組或第一個數組,其中第一個數值包含在數組中。然後我簡單地檢查我們迭代的輸入數組的下一個元素是否等於結果數組中最後一個數組的最後一個值加上1(即,如果它是下一個連續元素)。如果是,我將它追加到最後一個列表中。否則,我用它中的那個元素開始一個新的列表,並將它追加到結果數組中。
很好的答案,謝謝 – bluexuemei
使用哈希你可以這樣做:
counter = 0
groups = {}
old_array.each_with_index do |e, i|
groups[counter] ||= []
groups[counter].push old_array[i]
counter += 1 unless old_array.include? e.next
end
new_array = groups.keys.map { |i| groups[i] }
有點晚了這個晚會,但是:
old_array.slice_when { |prev, curr| curr != prev.next }.to_a
# => [[1, 2, 3], [5], [7, 8, 9], [20, 21], [23], [29]]
+1。 'slice_when'被[添加](https://bugs.ruby-lang.org/issues/9826)到ruby版本'2.2',並且提供了比這些舊的答案更優雅的解決方案。 –
這是學校?你有什麼嘗試?你在尋求幫助還是爲了我們爲你做? – DutGRIFF
'new_array'的條件? –
相關問題:http://stackoverflow.com/q/3728660/38765 –