我正在尝试将给定的字符串转换为散列,其每个字符都是character = key和index = value。
例如,如果我有str = "hello"
,我希望它转换为{"h"=>0, "e"=>1, "l"=>2, "l"=>3, "o"=>4}
。
我创建了一个方法:
def map_indices(arr)
arr.map.with_index {|el, index| [el, index]}.to_h
end
#=> map_indices('hello'.split(''))
#=> {"h"=>0, "e"=>1, "l"=>3, "o"=>4}
问题是它跳过了第一个l
。如果我颠倒el
和index
:arr.map.with_index {|el, index| [index, el]}.to_h
的顺序,我会收到所有拼写出来的字母:{0=>"h", 1=>"e", 2=>"l", 3=>"l", 4=>"o"}
但是当我invert
时,我会获得跳过l
其中一个的相同哈希值。
map_indices('hello'.split('')).invert
#=> {"h"=>0, "e"=>1, "l"=>3, "o"=>4}
为什么这样表现如此?如何才能打印{"h"=>0, "e"=>1, "l"=>2, "l"=>3, "o"=>4}
?
答案 0 :(得分:6)
它可以完成,但会混淆其他Ruby程序员。普通哈希处理密钥" a"和另一个" a"相同。除非使用了一个鲜为人知的特征.compare_by_identity
:
h = {}.compare_by_identity
"hello".chars.each_with_index{|c,i| h[c] = i}
p h # => {"h"=>0, "e"=>1, "l"=>2, "l"=>3, "o"=>4}
答案 1 :(得分:2)
也许这会更好地满足您的目的。
"hello".each_char.with_index.with_object({}) { |(c,i),h| (h[c] ||= []) << i }
#=> {"h"=>[0], "e"=>[1], "l"=>[2, 3], "o"=>[4]}
答案 2 :(得分:1)
您可以使用的另一个选项是将两个枚举压缩在一起。
s = "hello"
s.chars.zip(0..s.size)
这会产生:[["h", 0], ["e", 1], ["l", 2], ["l", 3], ["o", 4]]
答案 3 :(得分:0)
我是Ruby新手,我确信这可以重构,但另一种选择可能是:
arr1 = "Hello".split(%r{\s*})
arr2 = []
for i in 0..arr1.size - 1
arr2 << i
end
o = arr1.zip(arr2)
a_h = []
o.each do |i|
a_h << Hash[*i]
end
p a_h.each_with_object({}) { |k, v| k.each { |kk,vv| (v[kk] ||= []) << vv } }
=&GT; {“H”=&gt; [0],“e”=&gt; [1],“l”=&gt; [2,3],“o”=&gt; [4]}