为啥我不能在 .each 方法之外修改数组?

Posted

技术标签:

【中文标题】为啥我不能在 .each 方法之外修改数组?【英文标题】:Why can't I modify the array outside of the .each method?为什么我不能在 .each 方法之外修改数组? 【发布时间】:2022-01-24 03:13:06 【问题描述】:
def adjacent_sum(arr)
  narr = []
  arr.each.with_index do  |num, index|
    narr << (arr[index] + arr[index+1])
  end
  return narr
end

print adjacent_sum([3, 7, 2, 11])
#=> [10, 9, 13], because [ 3+7, 7+2, 2+11 ]

adjacent_sum([2, 5, 1, 9, 2, 4])
#=> [7, 6, 10, 11, 6], because [2+5, 5+1, 1+9, 9+2, 2+4]

我正在尝试根据用户的输入来修改叙述。基本上试图让所有相邻的数字相加并返回一个新数组。

编写一个方法similar_sum,它接受一个数字数组并返回一个包含原始数组中相邻数字之和的新数组。请参阅示例。

我不熟悉 Ruby 及其思维方式。我不知道该问题使用哪种迭代方法,我知道有很多迭代方法。我可以走老路,只做一个 while 循环,但我想了解 .each 循环的机制。

这是错误信息:

/tmp/file.rb:5:in `+': nil can't be coerced into Integer (TypeError)
    from /tmp/file.rb:5:in `block in adjacent_sum'
    from /tmp/file.rb:3:in `each'
    from /tmp/file.rb:3:in `with_index'
    from /tmp/file.rb:3:in `adjacent_sum'
    from /tmp/file.rb:10:in `<main>'

【问题讨论】:

您确定您正确解释了粗体字的问题陈述吗?你给出的例子是那个声明中提到的例子吗?如果是这样,我会认为问题的陈述措辞不佳,这当然不是你的错。看你的第一个例子,[3, 7, 2, 11]3 有一个相邻的元素,7,所以我认为3 的相邻元素的总和是77 有两个相邻的元素,32,它们的和是 5,以此类推,导致所需的数组是 [7,5,18,2] 是的。谢谢。 【参考方案1】:

您的循环正在遍历列表的每个元素。让我们以您的第一个示例为例。

[3, 7, 2, 11]

好的,我们正在迭代。首先,我们点击 3(我们添加 7,因为它是下一个)。接下来,我们点击 7(我们将添加 2)。第三,我们击中 2(加 11)。最后,我们达到了 11,我们要添加什么?我们正在添加 arr[4],它不存在,因此您的错误。

each(以及它的所有许多变体)从根本上说,您正在获取底层列表的每个元素。在您的情况下,您需要除最后一个元素之外的所有元素,因为您需要能够添加“下一个”元素才能执行添加。你可以像这样显式跳过最后一个元素

arr.each.with_index do  |num, index|
  if index < arr.size - 1
    narr << (arr[index] + arr[index+1])
  end
end

但这并不比直接的while 循环更好。 Ruby 的所有可枚举方法的重点是为工作选择正确的工具,在这种情况下,Ruby 的Enumerable 就是这个工具。 each_cons 为您提供了一个包含 N 个相邻元素的滑动窗口。所以我们可以写

def adjacent_sum(arr)
  arr.each_cons(2).map  |x, y| x + y 
end

这是 Ruby 的 Enumerable 模块的强大之处。一旦你有了一个理解迭代的高级构造,它就会提供大量工具来智能地迭代数据结构,这就是它比普通的while 循环更有用的原因。

【讨论】:

@CarySwoveland 我想我必须不同意。 OP 的第一个示例表明[3, 7, 2, 11] 应该产生[10, 9, 13],这是(a)比原始列表短一个元素,并且(b)与我写的答案一致。 我对没有仔细阅读问题感到内疚。请参阅我对这个问题的评论。 或者arr.each_cons(2).map(&amp;:sum)(也适用于2个以上)【参考方案2】:
def adjacent_sum(arr)
narr = []
l = arr.length
  
arr.each.with_index do  |num,index|
if index < arr.size-1
  narr << arr[index] + arr[index+1]
  end
end
return narr
end

print adjacent_sum([3, 7, 2, 11]) #=> [10, 9, 13], because [ 3+7, 7+2, 2+11 ]
puts
print adjacent_sum([2, 5, 1, 9, 2, 4]) #=> [7, 6, 10, 11, 6], because [2+5, 5+1, 1+9, 9+2, 2+4]
puts

我添加了 if 条件,以确保不会根据数组的索引评估数组并且代码有效: 如果索引

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于为啥我不能在 .each 方法之外修改数组?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能在方法之外调用变量? [复制]

Java:为啥我不能在 main 之外调用这个方法? [关闭]

为啥我不能在主类中创建除主方法之外的另一个方法?

为啥numpy数组的astype方法在转换类型时不修改输入?

为啥要从方法修改变量? [复制]

如何使用 jquery each() 方法在数组中追加多个对象