3

我想知道为什么以下内容不会修改数组。

我有这个:

@card.map!.with_index {|value, key|  key.even? ? value*=2 : value}

它只是迭代一个数组,并将所有偶数键的值加倍。

然后我做:

@card.join.split('').map!{|x| x.to_i}

它将数组连接成一个巨大的数字,将它们拆分为单独的数字,然后将它们映射回数组中的整数。从第 1 步到第 2 步的唯一真正变化是第 1 步看起来像 a=[1,2,12],而第 2 步看起来像 a=[1,2,1,2]。对于第二步,即使我使用 .map!当我 p @card 时,它在第一步之后看起来完全一样。如果我想继续使用他们的新数组,我必须将第二步 = 设置为某些东西。为什么是这样?有没有.map!在第二步中没有修改数组到位?还是方法的链接否定了我这样做的能力?干杯。

4

2 回答 2

2

tldr:如果该链中的每个方法都是就地修改方法,则方法链仅就地修改对象。

这种情况下的重要区别是您在对象上调用的第一个方法。您的第一个示例map!将此称为修改数组的方法。with_index在这个例子中并不重要,它只是改变了map!.

您的第二个示例调用join您的数组。join不会就地更改数组,但它会返回一个完全不同的对象:一个字符串。然后split是字符串,它会创建一个新数组,下面map!会修改数组。

因此,在您的第二个示例中,您需要再次将结果分配给您的变量:

@card = @card.join.split('').map{ |x| x.to_i }

可能有其他方法来计算所需的结果。但是由于您没有提供输入和输出示例,因此不清楚您要实现什么。

于 2014-09-04T21:10:08.490 回答
2

有没有.map!在第二步中没有修改数组到位?

是的,确实如此,但是它修改的数组不是@card。该split()方法返回一个新数组,即不是@card 的数组,并且map!就地修改新数组。

看一下这个:

tap{|x|...} → x
Yields [the receiver] to the block, and then returns [the receiver]. 
The primary purpose of this method is to “tap into” a method chain, 
in order to perform operations on intermediate results within the chain.  

@card = ['a', 'b', 'c']
puts @card.object_id

@card.join.split('').tap{|arr| puts arr.object_id}.map{ |x| x.to_i }  #arr is whatever split() returns

--output:--
2156361580
2156361380

ruby 程序中的每个对象都有一个唯一的 object_id。

于 2014-09-04T21:45:46.747 回答