Ruby .slice_when是否有一种方法可以在一行中有3个字符相等时对数组进行切片?

时间:2017-02-21 03:03:29

标签: ruby

我试图解决的问题的一部分是取一个数字并找到它连续有3个数字的时间。我已经尝试过两种方法来做到这一点,但都没有按计划运作。

在数字451999277中,999将连续三个数字和所需的输出。

#first bit of code worked for 451999277, but did not work with the number 10560002 
#which should return 000 but I am left with an empty array []

array2 = []
array = num1.to_s.chars
array.map {|x| array2 << x if x == array[array.index(x) + 1] && x == array[array.index(x) + 2]}


#I then tried to use .slice_when which also did not work.

num1.to_s.chars.slice_when{ |x, y, z| x == y && x == z}.to_a

有更好的方法吗?包括我没试过的东西?第一段代码似乎适用于大量输入,但同样不是10560002。

这是一个编辑...我现在意识到.index可能正在返回x发生的第一个索引....在这个10560002中...它将是索引1 ...仍在寻找解决方案

再次编辑,弄明白了!

array2 = []
array = num1.to_s.chars
array.each_with_index.map {|x, i| array2 << x if x == array[i + 1] && x == array[i + 2]}

2 个答案:

答案 0 :(得分:2)

>> 451999277.to_s.chars.chunk(&:itself).select{|_, a| a.size == 3}.map(&:first)
=> ["9"]
  • chunk找到评估为相同值的连续元素
  • select允许您仅采用长度为3的子序列

答案 1 :(得分:0)

r = /
    (\d)     # match a digit in capture group 1
    (\1{2,}) # match two or more digit that equal the contents of capture group 1,
             # in capture group 2
    /x       # free-spacing regex definition mode.

n = 239994566666

n.to_s.scan(r).map { |a| a.join.to_i }
  #=> [999, 66666]

步骤如下。

s = n.to_s
  #=> "239994566666" 
b = s.scan(r)
  #=> [["9", "99"], ["6", "6666"]] 
b.map { |a| a.join.to_i }
  #=> [999, 66666] 

请参阅String#scan的文档,尤其是捕获组的处理方法。捕获组1需要捕获要重复的第一个数字。为了使扫描返回\1{2,},我们需要将其放在第二个捕获组中。