自动创建哈希

Creating a hash automatically

我有一个数组 (array = ["home", "style", "honor", "home" ] 我想做的是从这个数组创建一个散列,如下所示:

hash = { "home" => 1, "style" => 2, "honor" => 3} #Array has two "home" element but I should give one value ("home" => 1) to both.

但是我想知道有什么简单的方法可以做到这一点吗?例如如果 i = 1 和 "home" => 1 然后我将是 2,遵循 "style" => 2。我应该使用循环,enmerables 吗?或者有更好的方法吗?

我们需要做的第一件事是从 Array. For that, we can use the Enumerable#uniq 方法中删除重复元素:

array.uniq
#=> ['home', 'style', 'honor']

接下来,我们需要将每个元素与其索引配对。为此,我们可以使用 Enumerable#each_with_index method, which gives us an Enumeratoryield 原始元素及其索引的二元数组:

array.uniq.each_with_index
#=> #<Enumerator: ['home', 'style', 'honor']:each_with_index>

我们可以通过将 Enumerator 转换为 Array:

来了解使用 Enumerator 时会发生什么
array.uniq.each_with_index.to_a
#=> [['home', 0], ['style', 1], ['honor', 2]]

索引不一,但我们可以使用 Enumerable#map:

来解决这个问题
array.uniq.each_with_index.map {|el, i| [el, i.succ] }
#=> [['home', 1], ['style', 2], ['honor', 3]]

或者,我们可以稍后在创建 Hash by using the Hash#transform_values 方法后修复它。

另一种可能性是首先使用带有可选偏移量参数的 Array#each and then use the Enumerator#with_index 方法将 Array 转换为 Enumerator

array.uniq.each.with_index(1)
#=> #<Enumerator: #<Enumerator: ['home', 'style', 'honor']:each>:with_index(1)>

array.uniq.each.with_index(1).to_a
#=> [['home', 1], ['style', 2], ['honor', 3]]

为了创建 Hash,我们需要做的就是使用 Enumerable#to_h 方法将我们已有的双元素“对”转换为键值对。 Enumerable#to_h 也采用可选块,这是我们转换索引的另一种可能方式。

array.uniq.each.with_index(1).to_h
array.uniq.each_with_index.to_h {|el, i| [el, i.succ]}
array.uniq.each_with_index.to_h.transform_values(&:succ)
#=> { 'home' => 1, 'style' => 2, 'honor' => 3 }

这是一种单行方法:

array
  .uniq
  .each_with_object({})
  .each_with_index { |(item, hash), index| 
      hash[item] = index + 1 
    }

基本上,我首先删除重复项,然后使用手头的散列和索引遍历数组(现在本质上是一个集合),然后将下一个索引分配给每个项目。我为每个结果加了 1 以匹配您想要的结果。

所需的散列可以一次获得,从而避免创建临时数组。

array = ["home", "style", "honor", "home", "style", "hello"] 
e = 1.step
array.each_with_object({}) { |x,h| h[x] = e.next unless h.key?(x) }
  #=> {"home"=>1, "style"=>2, "honor"=>3, "hello"=>4}

查看 Numeric#step 的形式,即 returns 一个枚举数。密钥查找 (h.key?(x)) 非常快,所需时间几乎与散列的大小无关。