拆分数组子阵列基于价值 [英] Split array into sub-arrays based on value
问题描述
我一直在寻找一个阵列相当于字符串#分裂
在Ruby中的核心,并惊讶地发现,它并不存在。难道还有比以下基于值的阵列分成多个子阵列更优雅的方式?
I was looking for an Array equivalent String#split
in Ruby Core, and was surprised to find that it did not exist. Is there a more elegant way than the following to split an array into sub-arrays based on a value?
class Array
def split( split_on=nil )
inject([[]]) do |a,v|
a.tap{
if block_given? ? yield(v) : v==split_on
a << []
else
a.last << v
end
}
end.tap{ |a| a.pop if a.last.empty? }
end
end
p (1..9 ).to_a.split{ |i| i%3==0 },
(1..10).to_a.split{ |i| i%3==0 }
#=> [[1, 2], [4, 5], [7, 8]]
#=> [[1, 2], [4, 5], [7, 8], [10]]
修改:对于那些有兴趣,这引发了此请求的现实世界的问题,可以在<一看到href=\"http://stackoverflow.com/questions/4798976/nokogiri-need-to-turn-markup-partitioned-by-hr-into-divs/4801341#4801341\">this回答,在这里我用@ FD的回答下面的实现。
Edit: For those interested, the "real-world" problem which sparked this request can be seen in this answer, where I've used @fd's answer below for the implementation.
推荐答案
我试着打高尔夫球了一点,仍然没有一个单一的方法,但:
I tried golfing it a bit, still not a single method though:
(1..9).chunk{|i|i%3==0}.reject{|sep,ans| sep}.map{|sep,ans| ans}
或更快:
(1..9).chunk{|i|i%3==0 || nil}.map{|sep,ans| sep&&ans}.compact
此外,可枚举#块
似乎是红宝石1.9+,但它是非常接近你想要什么。
Also, Enumerable#chunk
seems to be Ruby 1.9+, but it is very close to what you want.
例如,原始输出将是:
(1..9).chunk{ |i|i%3==0 }.to_a
=> [[false, [1, 2]], [true, [3]], [false, [4, 5]], [true, [6]], [false, [7, 8]], [true, [9]]]
(即 to_a
是使IRB打印一件好事,因为块
给你一个枚举,而不是一个数组)
(The to_a
is to make irb print something nice, since chunk
gives you an enumerator rather than an Array)
修改:注意上面的优雅的解决方案比最快的实现2-3倍慢:
Edit: Note that the above elegant solutions are 2-3x slower than the fastest implementation:
module Enumerable
def split_by
result = [a=[]]
each{ |o| yield(o) ? (result << a=[]) : (a << o) }
result.pop if a.empty?
result
end
end
这篇关于拆分数组子阵列基于价值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!