迭代数组以查找超过10的int并将这两个数字加在一起

Mik*_*eft 1 ruby arrays iteration

尝试迭代和数组以及任何10或更高的数字,拆分这些数字并将它们加在一起,例如:10 > "1" "0" > 1.

我能够遍历数组并实现它.然而,它返回nil而不是digits < 9.

def over_ten_sum
  #splits the numbers over 10 into seperate digit and sums them
  square_odd.map do |num|
    if num > 9
      num.to_s.chars.each_slice(2).map { |num_1, num_2| num_1.to_i + num_2.to_i }
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

使用[6, 4, 10, 2, 14, 7, 8, 4, 6, 7, 18, 4]它的值返回:

=> [nil, nil, [1], nil, [5], nil, nil, nil, nil, nil, [9], nil]
Run Code Online (Sandbox Code Playgroud)

我想要输出 [6, 4, 1, 2, 5, 7, 8, 6, 7, 9, 4]

只是没有看到这里的脱节.提前感谢您的任何见解.

Car*_*and 5

假设你要写

[1, 2, 3].map { |n| }
  #=> [nil, nil, nil]
Run Code Online (Sandbox Code Playgroud)

的阵列nil被返回是因为map返回nil用于n如果n没有被分配在所述块的值.同样的,

[1, 2, 3].map { |n| 2*n if n > 1 }
  #=> [nil, 4, 6]
Run Code Online (Sandbox Code Playgroud)

这与OP的代码问题非常相似.如果不想nil在返回的数组中使用s,则只需将数组的每个元素映射为非零值:

[1, 2, 3].map { |n| n > 1 ? 2*n : n }
  #=> [1, 4, 6]
Run Code Online (Sandbox Code Playgroud)

现在让我们来看看这条线

num.to_s.chars.each_slice(2).map { |num_1, num_2| num_1.to_i + num_2.to_i }
Run Code Online (Sandbox Code Playgroud)

如果num = 34,则返回[7],除了7数组中的事实之外,这是正确的.另一方面,如果num = 134表达式返回[4, 4](即[1+3, 4]),我不期望这是想要的.但是,如果数字总是有两位数,则上面的表达式与:

num[0].to_i + num[1].to_i
Run Code Online (Sandbox Code Playgroud)

这简单得多.1为了使它更通用,你需要编写类似下面的内容2:

def over_nine_sum(arr)
  arr.map { |n| n > 9 ? n.to_s.each_char.reduce(0) { |t,s| t + s.to_i } : n }
end

over_nine_sum [12, 5, 71, 3]
  #=> [3, 5, 8, 3]
Run Code Online (Sandbox Code Playgroud)

请参阅Enumerable #reduce(aka inject).

@JörgWMittag注意到(见注释)单位数字(0-9)的数字总和与数字本身相同,因此不需要以不同方式处理这些数字.因此我们可以写

def sum_digits(arr)
  arr.map { |n| n.to_s.each_char.reduce(0) { |t,s| t + s.to_i } }
end

sum_digits [12, 5, 71, 3]
  #=> [3, 5, 8, 3]
Run Code Online (Sandbox Code Playgroud)

正如@ steenslag在评论中所建议的那样,这可以简化为

def sum_digits(arr)
  arr.map { |n| n.digits.sum }
end
Run Code Online (Sandbox Code Playgroud)

它使用Integer#digitsArray#sum这两个方法(两者都是Ruby v2.4中的新方法).

考虑以下步骤(对于sum_digits上面的第一个版本)n = 34:

n.to_s.each_char.reduce(0) { |t,s| t + s.to_i }
  #=> 34.to_s.each_char.reduce(0) { |t,s| t + s.to_i }
  #=> "34".each_char.reduce(0) { |t,s| t + s.to_i }
Run Code Online (Sandbox Code Playgroud)

现在reduce将块变量t("memo",它返回)初始化为零,并将第一个数字传递"34"给块并将其分配给块变量s:

t = 0
s = "3"
Run Code Online (Sandbox Code Playgroud)

块计算是:

t + s.to_i
  #=> 0 + "3".to_i
  #=> 3
Run Code Online (Sandbox Code Playgroud)

这是更新的值t.下一个,

s = "4"
t + s.to_i
  #=> 3 + "4".to_i
  #=> 3 + 4
  #=> 7
Run Code Online (Sandbox Code Playgroud)

1.另一个问题是,如果square_odd是局部变量,Ruby在评估它时会引发"未定义的变量或方法"异常.

2. n.to_s.each_char.reduce(0)...最好是n.to_s.chars.reduce(0)...因为chars返回一个临时数组而each_char返回一个枚举器.