inject真tm的神奇。
inject是我最喜欢用的方法,因为它可以使如下的代码变的更漂亮:
使用inject:
但是,如果这么写:
就会报错: undefined method `<<' for nil:NilClass
这是值得注意的地方,起码是我常犯错的一个地方。
inject([]) do |item ,i |这样的写法,每一步,item都会被设置为block的返回值。上面的例子里,第一步if语句显然返回了nil,所以当执行第二步迭代的时候,自然给nil对象调用了<< 这个方法,就报错了!
这个问题怎么解决 ?
当然在判断条件为false的情况下返回当前的这个item值就ok了,像下面这样:
完了来回顾一下inject方法两种用法:
inject是我最喜欢用的方法,因为它可以使如下的代码变的更漂亮:
arr1 = []
arr2 = [1,2,3]
arr2.each do |i|
arr1 << i + 1
end
p arr1
#=> [2, 3, 4]
arr2 = [1,2,3]
arr2.each do |i|
arr1 << i + 1
end
p arr1
#=> [2, 3, 4]
使用inject:
arr = arr2.inject([])
do|arr1, i|
arr1 << i + 1
end
p arr
#=>[2,3,4]
arr1 << i + 1
end
p arr
#=>[2,3,4]
但是,如果这么写:
arr = arr2.inject([])
do |arr1,i|
arr1 << i+1 if i%2 == 0
end
arr1 << i+1 if i%2 == 0
end
就会报错: undefined method `<<' for nil:NilClass
这是值得注意的地方,起码是我常犯错的一个地方。
inject([]) do |item ,i |这样的写法,每一步,item都会被设置为block的返回值。上面的例子里,第一步if语句显然返回了nil,所以当执行第二步迭代的时候,自然给nil对象调用了<< 这个方法,就报错了!
这个问题怎么解决 ?
当然在判断条件为false的情况下返回当前的这个item值就ok了,像下面这样:
arr = arr2.inject([])
do |arr1,i|
(i%2) == 0 ? (arr1 << i+1) : arr1
end
(i%2) == 0 ? (arr1 << i+1) : arr1
end
完了来回顾一下inject方法两种用法:
enum.inject(init_value) {|memo,obj| block}
enum.inject{ |memo,obj| block }
第一种,memo以init_value为初始值
第二种,memo以 enum里的第一个元素为初始值。
enum.inject{ |memo,obj| block }
第一种,memo以init_value为初始值
第二种,memo以 enum里的第一个元素为初始值。