【发布时间】:2019-11-22 21:38:27
【问题描述】:
Enumerable#map 在块产生后创建一个带有返回值的数组。
在这种情况下,说:
v = 'a'
26.times.map { |i| v.ord.+(i).chr }
# => ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
但是为什么下面的代码用相同的元素填充数组呢?
v = '`'
26.times.map { v.next! }
# => ["z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z"]
v = '`'
Array.new(26) { v.next! }
# => ["z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z"]
它们不应该都有元素 a 到 z 吗?
同样,这有效:
v = '`'
Array.new(26) { v = v.succ }
# => ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
其实我正在尝试做:
v = "\xf0\x9d\x93\xa9"
('a'..'z').reduce({}) { |h, i| h.merge(i.intern => v = v.succ) }
# => {:a=>"????", :b=>"????", :c=>"????", :d=>"????", :e=>"????", :f=>"????", :g=>"????", :h=>"????", :i=>"????", :j=>"????", :k=>"????", :l=>"????", :m=>"????", :n=>"????", :o=>"????", :p=>"????", :q=>"????", :r=>"????", :s=>"????", :t=>"????", :u=>"????", :v=>"????", :w=>"????", :x=>"????", :y=>"????", :z=>"????"}
但我在使用 succ! / next! 时得到了所有 z
v = "\xf0\x9d\x93\xa9"
('a'..'z').reduce({}) { |h, i| h.merge(i.intern => v.succ!) }
# => {:a=>"????", :b=>"????", :c=>"????", :d=>"????", :e=>"????", :f=>"????", :g=>"????", :h=>"????", :i=>"????", :j=>"????", :k=>"????", :l=>"????", :m=>"????", :n=>"????", :o=>"????", :p=>"????", :q=>"????", :r=>"????", :s=>"????", :t=>"????", :u=>"????", :v=>"????", :w=>"????", :x=>"????", :y=>"????", :z=>"????"}
除了succ!/next!不改变内存位置和object_id,v.succ!和v = v.succ不一样吗?
【问题讨论】:
-
关于您的问题:
(:a..:z).zip('????'..'????').to_h似乎更容易。 -
是的,这很酷!但是为什么 bang 方法不工作而赋值运算符工作呢?
-
它可以工作,但是你有一个数组引用同一个对象 26 次,而不是一个包含 26 个不同对象的数组。见下文。