使用并行赋值交换数组元素
出于对这个问题的兴趣,我对数组和方法调用的并行赋值进行了一些研究。这是一个典型的示例,尝试按数组中的两个成员的值交换它们:
deck = ['A', 'B', 'C']
#=> ["A", "B", "C"]
deck[deck.index("A")], deck[deck.index("B")] = deck[deck.index("B")], deck[deck.index("A")]
#=> ["B", "A"]
deck
#=> ["A", "B", "C"]
数组没有更改。但是,如果我们改变参数的顺序,它就会起作用:
deck[deck.index("B")], deck[deck.index("A")] = deck[deck.index("A")], deck[deck.index("B")]
#=> ["A", "B"]
deck
#=> ["B", "A", "C"]
我猜这与在赋值中调用 index
方法的顺序有关,但看不清楚。有人可以解释一下下面的顺序,以及为什么第一个示例不交换成员,而第二个示例却交换成员?
Intrigued by this question, I have played a bit with parallel assignment with arrays and method calls. So here's an paradigmatic example, trying to swap two members in an array, by their value:
deck = ['A', 'B', 'C']
#=> ["A", "B", "C"]
deck[deck.index("A")], deck[deck.index("B")] = deck[deck.index("B")], deck[deck.index("A")]
#=> ["B", "A"]
deck
#=> ["A", "B", "C"]
The array hasn't changed. But if we change the order of arguments, it works:
deck[deck.index("B")], deck[deck.index("A")] = deck[deck.index("A")], deck[deck.index("B")]
#=> ["A", "B"]
deck
#=> ["B", "A", "C"]
I guess it has to do with the order of calling the index
methods within the assignment, but not see it clearly. Can someone please explain the order of things underneath, and why the first example doesn't swap the member, and second does?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是预料之中的。它遵循 ruby 如何评估表达式。
暗示
注意:这里的字符串“A”和“B”仅供说明之用。 Ruby 不会在这里创建新的字符串对象。本质上是:
Array#index 在找到第一个匹配项时返回。
现在,
It is expected. It follows from how ruby evaluates expressions.
Implies
Note: strings 'A' and 'B' here are for illustration only. Ruby doesn't create new string objects here. Which essentially is:
Array#index returns when it finds the first match.
Now,
举个例子,比较一下用于搜索数组的机制,找到正确的索引,然后交换值,与使用哈希可以做的事情:
现在,如果 Ruby 有一个可分配的
values_at=
Hash 方法它可能会更干净:但是,唉,我们没有。哈希切片是 Perl 中非常强大的工具,也是我怀念 Ruby 的东西。
而且,是的,我知道我可以添加自己的可分配
values_at=
。Just as an example, compare the machinations used to search the array, find the correct indexes then swap the values, with what you could do using a Hash:
Now, if Ruby had an assignable
values_at=
Hash method it could be even cleaner:but, alas, we don't. Hash slicing is a very powerful tool in Perl and something I miss about Ruby.
And, yes, I know I can add my own assignable
values_at=
.M Rajesh 是对的,但他实际上必须思考才能解决问题。我太懒了!
这是显示所发生情况的 printf 调试方式。
M Rajesh is correct, but he actually had to think in order to work it out. I'm too lazy for that!
Here's a printf-debugging way of showing what happened.