如何在Ruby中实现slice_after(或将某些元素与某些后续元素组合在一起)?

时间:2014-03-24 22:47:02

标签: ruby enumerable slice

Enumerable#slice_before方法是非常有用的,如果元素上的某个条件满足,它就完全按照它所说的在一个元素之前的锡片上。例如,我使用它将某些数字分组到以下数字。

在我的情况下,ID 0xF00xFB应该与它们之后的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,回复是

  

[没有实施]的主要原因是没有人要求。

     

我现在没有足够的时间来实施它。

因此,我如何自己实施?

2 个答案:

答案 0 :(得分:2)

如果您使用的是Ruby 2.2.0或更高版本,则可以使用

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不变。