自动创建哈希
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 Enumerator
即 yield
原始元素及其索引的二元数组:
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)
) 非常快,所需时间几乎与散列的大小无关。
我有一个数组 (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 Enumerator
即 yield
原始元素及其索引的二元数组:
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)
) 非常快,所需时间几乎与散列的大小无关。