这个 #divmod 方法输出这个结果的作用是什么?

What is it that this #divmod method is doing to output this result?

提问人:jbk 提问时间:4/26/2023 最后编辑:jbk 更新时间:4/26/2023 访问量:54

问:

我有两个数组:

a = [7, 1, 65, 4, 13, 97]
b = []

我正在尝试通过以下代码将每个元素的 #divmod 返回值附加到 中:ab

b << a.map(&4.method(:divmod))

我原以为结果是:

b = [[1, 3], [0, 1], [16, 1], [1, 0], [3, 1], [24, 1]]

但相反,我得到:

b = [[[0, 4], [4, 0], [0, 4], [1, 0], [0, 4], [0, 4]]]

我不明白为什么。谁能解释一下我不明白的地方?

(我不得不使用,因为我需要将此代码用作方法块参数。&:

Ruby 方法 divmod

评论


答:

5赞 Stefan 4/26/2023 #1

您得到的结果有两个问题:

  1. 你得到的数组有一个额外的嵌套层
  2. (内部)值不符合预期

要解决 (1) 问题,您必须分配结果而不是附加结果,即map

b = a.map(...)

关于(2),您的代码等同于:

a.map { |n| 4.divmod(n) }
#=> [[0, 4], [4, 0], [0, 4], [1, 0], [0, 4], [0, 4]]

而你想要:(注意,现在交换了)n4

a.map { |n| n.divmod(4) }
#=> [[1, 3], [0, 1], [16, 1], [1, 0], [3, 1], [24, 1]]

我不得不使用,因为我需要使用此代码作为方法参数&:

我不确定你的意思,但如果你不想有一个明确的块参数,你可以用以下方式传递一个 proc 或 lambda:&

divmod4 = ->(n) { n.divmod(4) }

b = a.map(&divmod4)
#=> [[1, 3], [0, 1], [16, 1], [1, 0], [3, 1], [24, 1]]

但是,由于会将 proc 转换为块参数,因此上述等价于直接调用。只有当您想重用该过程时,您才需要这种方法,例如将其传递给不同的方法。&divmod4a.map { |n| n.divmod(4) }

评论

0赞 jbk 4/26/2023
感谢您@stefan清晰而有用的解释。仅供参考,我在帖子末尾想说的是,现在相应地更新了,我正在尝试将此代码作为块参数传递给另一个方法。具体来说,我要做的是将其传递到我编写的二叉树遍历方法中,该方法接受可选的块参数。所以这就是为什么我尝试使用策略传入(#divmod)方法,但该方法需要一个参数,因此需要语法,除了我想交换接收器和 4。a.map { |n| n.divmod(4)}&:&4.method(:divmod)
1赞 Stefan 4/26/2023
@jbk用于将 proc 或方法转换为块参数或直接使用块语法 ( 或 ) 没有什么不同。两者都将块参数传递给该方法。您可以使用其中之一。&{ .. }do ... end
0赞 jbk 4/26/2023
谢谢@stefan,我现在意识到了这一点。我只是想解决错误,因为它似乎不允许传入的方法 arg 接受它自己的 arg。多亏了您的帮助,我现在创建了一个 lambda; 并像这样传入它,效果很好👍🏻,尽管我意识到不需要重用代码,所以我无论如何都可以传递一个显式块🙈。虽然是学习 Procs、方法参数等的一个很好的练习。感谢您的指导。(&:method(arg))divmod4 = ->(n) { n.divmod(4) }tree.level_order(&divmod4)
1赞 Stefan 4/27/2023
@jbk 顺便说一句(因为你说了两次):请注意,这不是 + .它是 +,后者是一个普通符号。(当然,你不能将参数传递给符号)&:&:method&:method&:method
0赞 jbk 4/27/2023
当然,现在@stefan这是有道理的。我想我现在看到语法只是提示紧随其后的人接收 Symbol#to_proc 方法(?)。&:symbol