使用多个条件操作多个数组

时间:2016-11-19 08:10:24

标签: arrays ruby

a = [nil, nil, 40, 30]
b = [nil, 20, nil, 50]

我想:比较&湾如果两个位置都为零,则将它们设置为0.如果一个为零,则将其设置为等于非零#。如果两者都是非零,则设置保持不变。

换句话说,我正在寻找这个结果:

a = [0, 20, 40, 30]
b = [0, 20, 40, 50]

谢谢!

编辑:澄清,如果两者都是非零,则按原样返回。将这种情况排除在外的不好的例子,所以我在上面进行了编辑。

4 个答案:

答案 0 :(得分:2)

nil || x会产生x(因为nil的假值是ruby)

nil || 2   # fallback to second value if the first value is `nil`
# => 2
nil || nil || 0  # fallback to 0 if both values are 0
# => 0
2 || nil  # Use the first value
# => 2

使用这样的特征,您可以执行以下操作:

a = [nil, nil, 40, nil, -1]
b = [nil, 20, nil, nil, 2]

a, b = a.zip(b).map { |x, y| [x||y||0, y||x||0] }.transpose
# a => [0, 20, 40, 0, -1]
# b => [0, 20, 40, 0, 2]

答案 1 :(得分:1)

我会从:

开始
a = [nil, nil, 40, nil]
b = [nil, 20, nil, nil]

a = a.zip(b).map { |pair| pair.map(&:to_i).max }
b = a.dup

a #=> [0, 20, 40, 0]
b #=> [0, 20, 40, 0]

说明:zip构建一对数组,to_inil翻译为0。我不确定max,因为如果两个数组在某个索引处都不是nil,那么您没有定义要返回的内容。

答案 2 :(得分:1)

我想有人应该提供一个没有使用nil.to_i #=> 0"技巧"的传统解决方案。请注意,如果任一阵列的元素不是nil,则不会更改。

def modify(arr, other)
  arr.each_index { |i| arr[i] = (other[i].nil? ? 0 : other[i]) if arr[i].nil? }
  arr
end

a = [nil, nil, 40, 30]
b = [nil, 20, nil, 50]

modify a,b
  #=> [0, 20, 40, 30] 
modify b,a
  #=> [0, 20, 40, 50] 

a #=> [0, 20, 40, 30] 
b #=> [0, 20, 40, 50] 

答案 3 :(得分:0)

a.each_with_index.map { |val,i| [val.to_i,b[i].to_i].max }
=> [0, 20, 40, 0]

nil.to_i返回0,这是一件非常酷的事情,因为那时你正在比较两个相似的东西,你不必进行零检查这是一个常见的代码气味。

更新:在其中一个答案中查看zip方法的使用:

a.zip(b).map {|a,b| [a.to_i, b.to_i].max }

更优雅一点。有关zip的更多信息,请参阅http://apidock.com/ruby/Array/zip