按照特定值将Ruby数组分组

10

我有一个数组,我希望只选择在两个指定值之间的元素。

例如,我有一个像这样的数组:

a = ["don't want", "don't want", "Start", "want", "want", "Stop", "don't want", "Start", "want", "Stop", "don't want"]

我想在数组中调用一个方法,该方法捕获"Start"和"Stop"之间的元素(包括"Start"和"Stop"元素)。结果数组应如下所示:

[["Start", "want", "want", "Stop"], ["Start", "want", "Stop"]]

我找不到这样的方法,所以我尝试写了一个:

class Array
  def group_by_start_and_stop(start = "Start", stop = "Stop")
    main_array = []
    sub_array = []

    group_this_element = false

    each do |e|
      group_this_element = true if e == start

      sub_array << e if group_this_element

      if group_this_element and e == stop
        main_array << sub_array
        sub_array = []
        group_this_element = false
      end
    end

    main_array
  end
end

这个方法可以工作,但是对我来说似乎过于繁琐。所以我有两个问题:是否已经存在类似的方法?如果没有,有什么方法可以使我的group_by_start_and_stop方法更好?


嵌套分隔符(['Start','want','Start','want','Stop','Stop'])怎么办?这是一个在另一个开始/停止内的开始/停止,重叠的间隔还是无效的? - mu is too short
在这种情况下,我想要的是从“Start”和第一个“Stop”之间的所有内容。然后它会再次开始。因此,根据您的示例,我希望结果是:[["Start", "want", "Start", "want", "Stop"]]。 - Glenn
5个回答

7
那是一个完美的例子,翻转器非常有用!
a.select {|i| true if (i=="Start")..(i=="Stop")}.slice_before("Start").to_a

虽然不是太出名的功能,但仍然非常酷!与slice_before一起使用,你可以得到你想要的结果!


太好了的决定!a.select {|i| true if (i=="Start")..(i=="Stop") } 就足够了。 - Konstantin Ilchenko
1
我喜欢那个条件,不知道那是可能的!但是,结果并不是预期的结果,你仍然必须将其呈现为一个数组的数组。 - ChuckE
好的!我用 slice_before 修复了它。 - Jean-Louis Giordano
感谢所有的建议。我发现这个非常有效。 - Glenn

1
a.each_with_index.select{|s, i| s.eql?("Start") or s.eql?("Stop")}
                 .map{|s, i| i}
                 .each_slice(2)
                 .map{|s, f| a[s..f]}

1
a.inject [] do |m, e|
  if e == 'Start'
    @state = true
    m << []
  end
  m.last << e if @state
  @state = false if e == 'Stop'
  m
end

0
a.join('^').scan(/Start.*?Stop/).map { |x| x.split('^') }
=> [["Start", "want", "want", "Stop"], ["Start", "want", "Stop"]]

符号^似乎很少见,所以它可能不会与其他原始符号混合。


0

:dummy 是为了确保从 slice_before 返回的第一个块是不需要的。

p [pres = :dummy, *a].slice_before{|e|
  prev, pres = pres, e
  prev == "Stop" or pres == "Start"
}
.select.with_index{|_, i| i.odd?}
# => => [["Start", "want", "want", "Stop"], ["Start", "want", "Stop"]]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接