Ruby - 将字符串转换为哈希值,每个字符作为键,索引作为值?

时间:2017-03-29 16:44:33

标签: ruby hash

我正在尝试将给定的字符串转换为散列,其每个字符都是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。如果我颠倒elindexarr.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}

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]}