36

我正在将数组转换为哈希,其中键是索引,值是该索引处的元素。

这是我的做法

# initial stuff
arr = ["one", "two", "three", "four", "five"]
x = {}

# iterate and build hash as needed
arr.each_with_index {|v, i| x[i] = v}

# result
>>> {0=>"one", 1=>"two", 2=>"three", 3=>"four", 4=>"five"}

有没有更好(在任何意义上的“更好”这个词)的方式来做到这一点?

4

7 回答 7

46
arr = ["one", "two", "three", "four", "five"]

x = Hash[(0...arr.size).zip arr]
# => {0=>"one", 1=>"two", 2=>"three", 3=>"four", 4=>"five"}
于 2013-01-25T19:00:49.957 回答
27

红宝石 < 2.1:

Hash[arr.map.with_index { |x, i| [i, x] }]
#=> {0=>"one", 1=>"two", 2=>"three", 3=>"four", 4=>"five"}

红宝石 >= 2.1:

arr.map.with_index { |x, i| [i, x] }.to_h
于 2013-01-25T19:14:09.590 回答
4
x = Hash.new{|h, k| h[k] = arr[k]}
于 2013-01-25T19:46:27.433 回答
3
%w[one two three four five].map.with_index(1){ |*x| x.reverse }.to_h

(1)如果要从 开始索引,请删除0

于 2016-01-15T22:57:36.973 回答
2

这是一个使用Object#tap, 将值添加到新创建的哈希的解决方案:

arr = ["one", "two", "three", "four", "five"]

{}.tap do |hsh|
  arr.each_with_index { |item, idx| hsh[idx] = item }
end
#=> {0=>"one", 1=>"two", 2=>"three", 3=>"four", 4=>"five"}
于 2018-06-25T11:33:56.113 回答
2

已经有很多好的解决方案,只需添加一个变体(前提是您没有重复的值):

["one", "two", "three", "four", "five"].map.with_index.to_h.invert
# => {0=>"one", 1=>"two", 2=>"three", 3=>"four", 4=>"five"}
于 2019-08-23T04:47:09.207 回答
1

您可以使用猴子补丁Array来提供一种新方法:

class Array
  def to_assoc offset = 0
    # needs recent enough ruby version
    map.with_index(offset).to_h.invert
  end
end

现在你可以这样做:

%w(one two three four).to_assoc(1)
# => {1=>"one", 2=>"two", 3=>"three", 4=>"four"}

这是我在 Rails 应用程序中执行的常见操作,因此我将这个猴子补丁保存在初始化程序中。

于 2016-11-08T13:58:48.210 回答