【问题标题】:Modify an Array in Place - Ruby就地修改数组 - Ruby
【发布时间】:2014-10-29 17:39:54
【问题描述】:

我想知道为什么下面不会修改数组。

我有这个:

@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!在第二步中没有修改数组到位?还是方法的链接否定了我这样做的能力?干杯。

【问题讨论】:

  • 显示你的语料库。显示你的错误。显示您的预期输出。
  • 第一个代码块中的表达式value*=2 具有误导性;你应该改写value * 2

标签: ruby arrays loops enumerable iterate


【解决方案1】:

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

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

您的第二个示例在您的阵列上调用joinjoin 并没有就地改变数组,但它返回一个完全不同的对象:一个字符串。然后你 split 字符串,它创建一个新数组,下面的 map! 修改 new 数组。

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

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

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

【讨论】:

    【解决方案2】:

    .map!在第二步中没有就地修改数组?

    是的,确实如此,但是它修改的数组不是@card。 split() 方法返回一个新数组,即不是@card 的数组,然后映射!就地修改新数组。

    看看这个:

    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。

    【讨论】:

    • @HectorOfTroy407,单击 spickermann 答案左侧的复选标记的轮廓。您还可以通过单击 0 上方的向上箭头来支持 spickermann 的答案。
    猜你喜欢
    • 1970-01-01
    • 2019-03-18
    • 2019-02-20
    • 1970-01-01
    • 2018-07-25
    • 1970-01-01
    • 2022-10-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多