多行块与行内块的行为不同



我很好奇为什么这些会产生不同的输出。期望的输出是ActiveRecord记录的数组。

当使用内联块时,它似乎正在做ActiveRecord查找,但随后将原始数组(减去rejected元素)嵌套在另一个数组内,并将嵌套数组追加到变量。

当使用多行块时,会发生预期的行为,即ActiveRecord查找发生,并且已识别的记录被附加到变量中。

x = []
y = ["", "1353", "1155"]
x << y.reject!(&:empty?).each { |i| User.find(i) }
# => ["1353", "1155"]
x
#=> [["1353", "1155"]]

x = []
y = ["", "1353", "1155"]
y.reject!(&:empty?)
y.each do |i|
x << User.find(i)  
end  
# => ["1353", "1155"]
x
#=> [#<User:0x00007fc7fbacc928
#  id: 1353,
#  login: nil,
...

不同的是。each返回数组本身,所以

[1,2,3].each { nil }
# [1,2,3]

所以你在X中附加了被拒绝的Y数字,而你的。each在第一个例子中是无用的(这也是为什么它是数组的数组,因为'<<'将元素数组插入到数组中,而不是所有的单个元素)


在你的第二个例子中,你的'each'实际上是将元素添加到块内的数组中,所以没有"return"依赖。如果你想在单行上做,你就必须做

y.reject(&:empty?).each { |i| x << User.find(i) }

所以它会在de块内进行计算,如果你想让每个循环返回块内的值,你应该使用'map'而不是'each',并使用'concat'或'+'来求和数组(所以它求和或concat每个单独的元素),所以

x.concat(y.reject(&:empty?).map{ |i| User.find(i) })

OBS:正如@tadman在评论中建议的那样,我也删除了"bangs"对于拒绝,如"拒绝!"方法不期望总是返回所有值,查看其注释以获取更多信息

相关内容

  • 没有找到相关文章

最新更新