使用each_slice从字符串结尾开始分割输入?

时间:2014-05-06 14:44:52

标签: ruby

我想将字符串拆分为三个数组,如所需输出所示。像这样使用Array#each_slice 1_223_213_213.to_s.split('').each_slice(3){|arr| p arr }

Current output:                  Desired output
 # ["1", "2", "2"]                # ["0", "0", "1"]
 # ["3", "2", "1"]                # ["2", "2", "3"]
 # ["3", "2", "1"]                # ["2", "1", "3"]
 # ["3"]                          # ["2", "1", "3"]

必须使用(0..trillion)的数字。我在下面发布了我的解决方案。希望大家能给我一些优化或替代工具的建议吗?

6 个答案:

答案 0 :(得分:4)

尝试使用零填充左边距,直到字符串长度为“切片”目标的偶数倍:

def slice_with_padding(s, n=3, &block)
  s = "0#{s}" while s.to_s.size % n != 0
  s.to_s.chars.each_slice(n, &block)
end

slice_with_padding(1_223_213_213) { |x| puts x.inspect }
# ["0", "0", "1"]
# ["2", "2", "3"]
# ["2", "1", "3"]
# ["2", "1", "3"]

slice_with_padding(12_345, 4) { |x| puts x.inspect }
# ["0", "0", "0", "1"]
# ["2", "3", "4", "5"]

答案 1 :(得分:2)

您可能会发现这一点更令您满意:

def slice_by_3(n)
  n = n.to_s
  l = n.length
  [*n.rjust(l % 3 == 0 ? l : l + 3 - l % 3, '0').chars.each_slice(3)]
end

slice_by_3 2_123_456_544_545_355
=> [["0", "0", "2"], 
    ["1", "2", "3"], 
    ["4", "5", "6"], 
    ["5", "4", "4"], 
    ["5", "4", "5"], 
    ["3", "5", "5"]] 

或者,如果您想要更通用的解决方案:

def slice_by_n(num, n=3)
  num = num.to_s
  l = num.length
  [*num.rjust(l % n == 0 ? l : l + n - l % n, '0').chars.each_slice(n)]
end

答案 2 :(得分:0)

以下是该问题的可能解决方案:

def slice_by_3 number
  initial_number = number.to_s.split('').size 
  number = "00#{number}" if initial_number == 1
  modulus = number.to_s.split(/.{3}/).size
  padleft = '0' * ( (modulus*3) % number.to_s.split('').size )
  ("#{padleft}#{number}").split('').each_slice(3){|arr| p arr }
end

slice_by_3 2_123_456_544_545_355
 # ["0", "0", "2"]
 # ["1", "2", "3"]
 # ["4", "5", "6"]
 # ["5", "4", "4"]
 # ["5", "4", "5"]
 # ["3", "5", "5"]

看起来有点复杂,我想相信有更好的方法。感谢您的反馈。

答案 3 :(得分:0)

以下是几种方法

n = 1_223_213_213.to_s
n.rjust(n.size + n.size % 3,"0").chars.each_slice(3).to_a

OR

n.rjust(15,"0").chars.each_slice(3).drop_while{|a| a.join == "000"}

15是因为你声明最大值是万亿显然这个数字意味着很少,因为它拒绝包含所有零的所有结果,所以任何大于15的数字都可以被{{1}整除将适用于您的示例

答案 4 :(得分:0)

另一种方式:

def split_nbr(n)
  str = n.to_s
  len = str.size
  str.rjust(len + (3-len%3)%3, '0').scan(/.../).map(&:chars)
end  

split_nbr(  1_223_213_213)
  #=> [["0", "0", "1"], ["2", "2", "3"], ["2", "1", "3"], ["2", "1", "3"]]
split_nbr( 11_223_213_213)
  #=> [["0", "1", "1"], ["2", "2", "3"], ["2", "1", "3"], ["2", "1", "3"]]
split_nbr(111_223_213_213)
  #=> [["1", "1", "1"], ["2", "2", "3"], ["2", "1", "3"], ["2", "1", "3"]]

答案 5 :(得分:0)

def slice_by_3 number
  "000#{number}".split('').reverse
    .each_slice(3).to_a[0..-2].reverse
    .each { |arr| p arr.reverse }
end

slice_by_3 13_456_544_545_355
# ["0", "1", "3"]
# ["4", "5", "6"]
# ["5", "4", "4"]
# ["5", "4", "5"]
# ["3", "5", "5"]

此代码在向数字start添加3个零后反转整个数组。 each_slice(3)然后切换到适当的组(尽管是相反的)加上一个由["0","0","0"]["0","0"]["0"]组成的组,具体取决于数字的原始长度。

[0..-2]会删除最后一组零。然后将组反转,并打印每组(反向)。