【问题标题】:hash assignment when (key => value) are stored in an array? (ruby)(key => value)存储在数组中时的哈希分配? (红宝石)
【发布时间】:2010-01-24 10:19:05
【问题描述】:

我有 散列 (@post) 的散列,我想保持散列键在数组 (@post_csv_order) 中的顺序,并且还想保留 关系键 =>数组中的值

我不知道数组中@post 哈希和 key => value 元素的最终数量。

我不知道如何在循环中为数组中的所有元素分配哈希。一个接一个@post_csv_order[0][0] => @post_csv_order[0][1] 工作得很好。

#  require 'rubygems'
require 'pp'

@post = {}

forum_id = 123           #only sample values.... to make this sample script work
post_title = "Test post"

@post_csv_order = [
  ["ForumID" , forum_id],
  ["Post title", post_title]  
]

if @post[forum_id] == nil
  @post[forum_id] = {
    @post_csv_order[0][0] => @post_csv_order[0][1],
    @post_csv_order[1][0] => @post_csv_order[1][1]
    #@post_csv_order.map {|element| element[0] => element[1]}
    #@post_csv_order.each_index {|index|        @post_csv_order[index][0] => @post_csv_order[index][1] }
  }
end

pp @post

所需的哈希分配应该是这样的

{123=>{"Post title"=>"Test post", "ForumID"=>123}}

【问题讨论】:

  • 请编辑您的问题以正确格式化...
  • 谢谢,提交后经常出现格式不正确的情况。我必须仔细检查。

标签: ruby arrays hash


【解决方案1】:

最好的方法是使用to_h

[ [:foo,1],[:bar,2],[:baz,3] ].to_h  #=> {:foo => 1, :bar => 2, :baz => 3}

注意:这是在 Ruby 2.1.0 中引入的。对于较旧的 Ruby,您可以使用我的 backports gem 和 require 'backports/2.1.0/array/to_h',或者使用 Hash[]

array = [[:foo,1],[:bar,2],[:baz,3]]
# then
Hash[ array ]  #= > {:foo => 1, :bar => 2, :baz => 3}

这在 Ruby 1.8.7 及更高版本中可用。如果您仍在使用 Ruby 1.8.6,您可以require "backports/1.8.7/hash/constructor",但您也可以使用to_h 反向端口。

【讨论】:

  • @Marc-Andre Lafortune:看起来不错。在我的情况下,代码是什么? @post[forum_id] = @post_csv_order 给我的是数组的散列而不是散列的散列。
  • 你调用了 Hash[] 吗?请参阅我的更新答案。如果使用 1.8.6,请不要忘记要求 backports
  • 我尝试了@post[forum_id] = Hash[ @post_csv_order ],现在我尝试了@post[forum_id] ||= Hash[ @post_csv_order ]。两者都给了我odd number of arguments for Hash (ArgumentError)
  • hm,你为什么在=前面使用||
  • 奇数个参数 => 我相信您使用的是 Ruby 1.8.6?您需要事先require "backports"。 ||= 见stackoverflow.com/questions/63998/hidden-features-of-ruby/…
【解决方案2】:

我不确定我是否完全理解您的问题,但我猜您想将二维数组转换为哈希。

所以假设你有一个数组,例如:

array = [[:foo,1],[:bar,2],[:baz,3]]

您可以使用以下方法构建哈希:

hash = array.inject({}) {|h,e| h[e[0]] = e[1]; h}
# => {:foo=>1, :bar=>2, :baz=>3}

您可以按正确的顺序检索密钥:

keys = array.inject([]) {|a,e| a << e[0] }
=> [:foo, :bar, :baz]

这是你要找的吗?

【讨论】:

  • @paradigmatic:也许,也许你没有完全理解,但你完全回答了:-) 我需要的只是hash = array.inject({}) {|h,e| h[e[0]] = e[1]; h},我在示例代码中将其更改为@post[forum_id] = @post_csv_order.inject({}) {|h,e| h[e[0]] = e[1]; h},它完全符合我的要求想做。明天我会在整个项目脚本中检查它。谢谢。
  • 从键值对数组构建散列的另一种方法是:Hash[*array.flatten]
  • @Wayne:确实,Hash[] 有一种更简单的方法,但是从 1.8.7 开始就不需要展平(如果您的任何键/值是数组,这实际上很危险) 看我的回答
  • @Wayne Conrad:哇。 @post[forum_id] = Hash[*@post_csv_order.flatten] 效果很好。谢谢
【解决方案3】:

答案总结

工作代码 #1

@post[forum_id] = @post_csv_order.inject({}) {|h,e| h[e[0]] = e[1]; h}

工作代码 #2

@post[forum_id] = Hash[*@post_csv_order.flatten]

工作代码 #3

@post[forum_id] ||= Hash[ @post_csv_order ] #requires 'require "backports"'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-19
    • 1970-01-01
    • 1970-01-01
    • 2017-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多