Arrays Ruby将数组数组转换为哈希数组

Arrays Ruby将数组数组转换为哈希数组,arrays,ruby,hash,Arrays,Ruby,Hash,拜托,我需要帮忙 在Ruby中,如果我有这个数组 array = [["a: 1", "b:2"],["a: 3", "b:4"]] 如何在ruby中获得这个哈希数组 aoh = [{:a => "1", :b => "2"},{:a => "3", :b => "4"}] 循环浏览您的项目,循环浏览其项目,创建新数组: array.map do |items| items.map do |item| k,v = item.split(":", 2)

拜托,我需要帮忙

在Ruby中,如果我有这个数组

array = [["a: 1", "b:2"],["a: 3", "b:4"]]
如何在ruby中获得这个哈希数组

aoh = [{:a => "1", :b => "2"},{:a => "3", :b => "4"}]

循环浏览您的项目,循环浏览其项目,创建新数组:

array.map do |items| 
  items.map do |item| 
    k,v = item.split(":", 2)
    { k.to_sym => v } 
  } 
} 
请注意,我们使用的是
map
而不是
each
,后者将返回一个数组。

请注意,这很可能是XY问题,而不是转换数组,更好的选择是以更好的方式构建起始数组

但是,您可以通过以下方式执行此操作:

aoh = array.map { |array| array.to_h { |string| string.split(':').map(&:strip) } }
# => [{"a"=>"1", "b"=>"2"}, {"a"=>"3", "b"=>"4"}]
以上内容将为您提供字符串键,这是更安全的选择。您可以将它们转换为符号,但它们应该。当数据来自用户或外部来源时,我会选择上面的方法

可以通过添加以下行来转换为符号:

# note that this line will mutate the aoh contents
aoh.each { |hash| hash.transform_keys!(&:to_sym) }
#=> [{:a=>"1", :b=>"2"}, {:a=>"3", :b=>"4"}]

正则表达式
/:*/
的内容是,“匹配一个冒号,后跟零个或多个(
*
)空格”
/\A\d+\z/
读取:“匹配字符串的开头(
\A
),后跟一个或多个(
+
)数字(
\d
),然后是字符串的结尾(
\z

步骤如下。第一步是将元素
arr[0]
传递到块,块变量
a
赋值并执行块计算

a = array[0]
  #=> ["a: 1", "b:2"]
b = a.flat_map { |s| s.split(/: */) }
  #=> ["a", "1", "b", "2"] 
c = b.map { |s| s.match?(/\A\d+\z/) ? s : s.to_sym } 
  #=> [:a, "1", :b, "2"]
d = Hash[*c]
  #=> {:a=>"1", :b=>"2"} 
a = array[1]
  #=> ["a: 3", "b:4"] 
b = a.flat_map { |s| s.split(/: */) }
  #=> ["a", "3", "b", "4"] 
c = b.map { |s| s.match?(/\d/) ? s : s.to_sym } 
  #=> [:a, "3", :b, "4"] 
d = Hash[*c]
  #=> {:a=>"3", :b=>"4"} 
我们看到数组
[“a:1”,“b:2”]
被映射到
{:a=>“1”,“b=>“2”}
。接下来元素
arr[1]
被传递到块,块变量
a
被赋值并执行块计算

a = array[0]
  #=> ["a: 1", "b:2"]
b = a.flat_map { |s| s.split(/: */) }
  #=> ["a", "1", "b", "2"] 
c = b.map { |s| s.match?(/\A\d+\z/) ? s : s.to_sym } 
  #=> [:a, "1", :b, "2"]
d = Hash[*c]
  #=> {:a=>"1", :b=>"2"} 
a = array[1]
  #=> ["a: 3", "b:4"] 
b = a.flat_map { |s| s.split(/: */) }
  #=> ["a", "3", "b", "4"] 
c = b.map { |s| s.match?(/\d/) ? s : s.to_sym } 
  #=> [:a, "3", :b, "4"] 
d = Hash[*c]
  #=> {:a=>"3", :b=>"4"} 
splat运算符(
*
)使
散列[*c]
计算为:

Hash[:a, "3", :b, "4"]

请参见。

我试图回答,但注意到了不寻常的语法。数据是以这种方式提供给您的,作为字符串对吗?第二个问题:在
上拆分是否足够,或者右侧是否可能包含该字符?空格是否可选,因为有人似乎缺少它。欢迎这样做!请参见““以及链接页面和”。我们很感激你可能是新来的,但我们确实希望你在这方面付出努力的证据。你在哪里找的?为什么没有帮助?如果是的话,那么您为测试所学内容而编写的代码在哪里?如果你没有写代码,为什么不呢?如果您这样做了,那么演示您遇到的问题的最小代码是什么,以及对问题的解释,最小输入数据和预期结果是什么?如果没有这一点,就很难对您有所帮助。
[[“a:1”、“b:2”]、[“a:3”、“b:4”]
不是数据的正常定义,尤其是对于散列数组而言。这看起来可疑地像是一个XY问题,您询问的是如何创建哈希,但在此步骤之前应该询问如何收集数据。“”这是一个奇怪的问题,但似乎足够清楚。是的,数据就像来自设备输出解析结果的字符串对。数据源在冒号后随机生成这些空格,卡里的答案是正确的为什么
哈希[]
优先于
数组#to _h
?这样做会更安全
。split(/:*/,2)
@tadman,我更喜欢
而不是_h
,特别是当与块一起使用时,就像3limin4t0r一样。我不知道为什么我选择了
散列::[]
。我现在讨厌我的答案,但出于教学原因,我会留下它。@Amadan,为什么更安全?如果有人担心其中一根弦可能会分裂成两段以外的东西,那么如果发生这种情况,是否最好提出一个例外(或者我没有领会你的意思)?取决于OP需要什么,因为他们没有回应@tadman的评论;但是额外的冒号会破坏你的代码。奇数个这样的元素将随着
ArgumentError(散列
的奇数个参数)而消亡,偶数将给出不可预见的结果;e、 g.
[[“姓名:魔法:聚会”,“姓名:吸血鬼:化装舞会”]
结果是
[{:姓名=>:Magic,:“聚会”=>:姓名,:吸血鬼=>:“化装舞会”}]
,没有错误。限制拆分使其行为正确。当存在>2次拆分时引发错误也是一个选项。除非OP声明每个字符串只有一个冒号,否则默认忽略它不是。我唯一的建议是使用
split(/:*/)
,这样您就可以放弃
。map(&:strip)
。与块一起使用很好,可选块在v2.6中是新的。与Cary的注释相同,在没有声明只有一个冒号的情况下,限制
拆分
是一个好主意。@CarySwoveland我考虑过这样做,但是
.map(&:strip)
也会删除键前或值后的空格。在我看来,在不知道字符串允许的语法的情况下,这是更安全的方法。但是,这可能不需要,具体取决于用例,
。split(/:*/)
可能就足够了。数据源在冒号之后随机生成这些空格