map 基本上是遍历对象的元素:
foo = [
['a', 'b'],
['c', 'd']
]
foo.map{ |ary| puts ary.join(',') }
# >> a,b
# >> c,d
在本例中,它传递每个子数组,分配给ary。
换个角度看:
foo.map{ |ary| puts "ary is a #{ary.class}" }
# >> ary is a Array
# >> ary is a Array
因为 Ruby 允许我们一次分配多个值,所以可以这样写:
foo.map{ |item1, item2| puts "item1: #{ item1 }, item2: #{ item2 }" }
# >> item1: a, item2: b
# >> item1: c, item2: d
如果map 正在对哈希数组进行迭代,则每次迭代都会产生块的子哈希:
foo = [
{'a' => 1},
{'b' => 2}
]
foo.map{ |elem| puts "elem is a #{ elem.class }" }
# >> elem is a Hash
# >> elem is a Hash
如果map 正在对哈希进行迭代,则每次迭代都会产生块的键/值对:
foo = {
'a' => 1,
'b' => 2
}
foo.map{ |k, v| puts "k: #{k}, v: #{v}" }
# >> k: a, v: 1
# >> k: b, v: 2
但是,如果你只给块一个参数,Ruby 会将键和值都分配给变量,所以你会看到它是一个数组:
foo.map{ |ary| puts "ary is a #{ary.class}" }
# >> ary is a Array
# >> ary is a Array
因此,当您遍历容器以及 Ruby 将值传递到 map 的块中时,您必须了解正在发生的多种事情。
除此之外,重要的是要记住map 将为传入的每个内容返回一个或多个值。map,又名collect,用于转换值。它不应该被用作each 的替代品,它只会迭代。在上面的所有示例中,我并没有真正展示 map 的正确使用,因为我试图展示传入的元素会发生什么。通常我们会这样做:
foo = [['a', 'b'], ['c', 'd']]
foo.map{ |ary| ary.join(',') }
# => ["a,b", "c,d"]
或者:
bar = [[1,2], [3,4]]
bar.collect{ |i, j| i * j }
# => [2, 12]
还有map! 改变被迭代的对象,而不是返回值。我建议避免使用map!,直到您清楚地知道它为什么对您有用,因为除非他们了解变量的传递方式以及数组和哈希的工作原理,否则它似乎会让人们感到困惑。
最好的办法是在 IRB 中使用map。您将能够更轻松地看到正在发生的事情。