Enumerable#slice_before
方法是非常有用的,如果元素上的某个条件满足,它就完全按照它所说的在一个元素之前的锡片上。例如,我使用它将某些数字分组到以下数字。
在我的情况下,ID 0xF0
到0xFB
应该与它们之后的ID分组,包括连续多个这些ID(它们是我的“修饰符”标志正在制作。我是这样做的:
# example code (for SSCCE)
code = '00FF1234F0AAF0BBF0CCCCF3F4F5AAAAAA'.split('').each_slice(2).map{|n| n.join.to_i 16 }
# grouping the modifiers (more may be added later, so array is used)
code = code.slice_before {|tkn| ![*0xF0..0xFB].include? tkn }.to_a
此后code
的结果是
[[0], [255], [18], [52, 240], [170, 240], [187, 240], [204], [204, 243, 244, 245], [170], [170], [170]]
然而,期望的结果是
[[0], [255], [18], [52], [240, 170], [240, 187], [240, 204], [204], [243, 244, 245, 170], [170], [170]]
我找到this entry on bugs.ruby-lang.org,回复是
[没有实施]的主要原因是没有人要求。
我现在没有足够的时间来实施它。
因此,我如何自己实施?
答案 0 :(得分:2)
Enumerable#slice_after
,因此您可以使用它:
modifiers = 0xF0..0xFB
hex_code = '00FF1234F0AAF0BBF0CCCCF3F4F5AAAAAA'
bytes = [hex_code].pack('H*').bytes
code = bytes.slice_after { |b| !modifiers.include? b }.to_a
p code # => [[0], [255], [18], [52], [240, 170], ...
答案 1 :(得分:1)
这不是我想要的优雅单行,但这可以完成工作:)
target = []
code.each do |i|
# if there is a previous element and it was one of the "modifiers"
if target.last && [*0xF0..0xFB].include?(target.last.last)
# append it to the current subarray
target.last << i
else
# otherwise, append a new subarray
target << [i]
end
end
您会在target
中找到所需的数组,code
不变。