用一对二块参数调用`Hash #map`

时间:2016-06-20 06:04:27

标签: arrays ruby hash

entries是哈希的地方:

entries = { foo: 1, bar: 2 }

这是我熟悉的语法:

entries.map { |key, val| "#{key} #{val}" }
#=> ["foo 1", "bar 2"]

这是我在教程中遇到的语法:

entries.map { |key_val| "#{key_val.first} #{key_val.last}" }
#=> ["foo 1", "bar 2"]

我是Ruby的新手,所以我很惊讶两种语法都能正常工作。我的问题是:

  1. 这两者有什么区别吗?

  2. 为什么这样做 - 是否因为哈希表对象以两种不同的方式实现Enumerable接口(提供map方法)?

2 个答案:

答案 0 :(得分:5)

不,它与哈希和枚举无关(好吧,差不多)。这是我称之为“数组解构”的东西。 Ruby有一种很好的方法可以将数组分开。假设你有这个双元素数组

projectId.AsString + "-comments-" + creationMomentString + "-" + _rand.nextInt() +  ".txt";
   ||                     ||               ||                         ||              ||
o7grn3qt              -comments-    0000001466400377645     -    -874329600          .txt

您可以通过单独访问它们来获取其元素

ary = [1, 2]

或者你可以通过将数组直接赋值给变量

来“解构”数组
a = ary.first # or ary[0]
b = ary.last # or ary[-1]

a, b = ary 将是数组的第一个元素a - 第二个(在这个特例中也是最后一个)。

您的示例中也会发生同样的事情。可枚举的b(这是each调用的),当在散列上使用时,会产生两个元素的数组,一个键及其值。

现在,如果块只有一个参数,那就是那个数组。如果它有两个,你的阵列将被拆开。

是的,更喜欢第一种方法。更具可读性。

答案 1 :(得分:0)

在Ruby中,Hash#eacheach的别名,换句话说,两种方法都指向same implementation。传递给each的块总是以双元素数组的形式接收键值对。

由于Enumerable模块的所有方法都是基于map方法实现的,因此所有可枚举方法包括{{1}}都将接收键值对作为数组参数。

这样就可以使用上面提到的两种语法。