从Ruby中的嵌套哈希和数组中提取值

时间:2015-09-22 17:08:41

标签: arrays ruby hash nested

我有一个看起来像这样的哈希:

h = { 
  a: [ ["c", "1"],["d","2"],["e","3"],["f","4"] ], 
  b: [ ["g","5"],["h","6"],["i","7"],["j","8"] ], 
  c: [ ["k","9"],["l","10"],["m","11"],["n","12"] ]
}

从中提取数字的最佳方法是什么,所以它看起来像这样?

[1,2,3,4,5,6,7,8,9,10,11,12]

我尝试了一些不同的东西,但它总是需要一个外部数组,我必须从each命令链中进入。

6 个答案:

答案 0 :(得分:6)

我愿意:

h.values.flatten(1).map{|x,y| y.to_i }

答案 1 :(得分:4)

这可以使用正则表达式完成。

hash.values.flatten.select { |v| v.match(/\d/) }.map(&:to_i)
  • 要获取值,请使用values方法

  • 要使数组成为一维数,请使用flatten方法。

  • 要进行过滤,请使用select方法,找到与数字的正则表达式匹配的字符串。

  • 最后,映射此数组以将元素转换为整数。

答案 2 :(得分:3)

对数字flatten使用selectregexp\d的组合:

=> a = { 
  a: [ ["c", "1"],["d","2"],["e","3"],["f","4"] ], 
  b: [ ["g","5"],["h","6"],["i","7"],["j","8"] ], 
  c: [ ["k","9"],["l","10"],["m","11"],["n","12"] ]
}
=> a.values.flatten.select { |x| x =~ /\d/ }.map(&:to_i)
#> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

其他方式flat_mapmap( )

reach inside the structure with parentheses to make things more explicit 功能

=> a = { 
  a: [ ["c", "1"],["d","2"],["e","3"],["f","4"] ], 
  b: [ ["g","5"],["h","6"],["i","7"],["j","8"] ], 
  c: [ ["k","9"],["l","10"],["m","11"],["n","12"] ]
}
=> a.flat_map { |_, (n, z, i, x)| [n, z, i, x] }.map { |_, i| i.to_i }
#> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

答案 3 :(得分:3)

<强>代码

h[:a][0][0]

示例

您的哈希值h = { a: [["8c", "1"],["d","2"],["e","3"],["f","4"]], b: [["g","5"],["h","6"],["i","7"],["j","8"]], c: [["k","9"],["l","10"],["m","11"],["n","12"]] } pull_numbers(h) #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] 略有修改:

c = h.values
  #=> [[["8c", "1"], ["d", "2"], ["e", "3"], ["f", "4"]],
  #    [["g", "5"], ["h", "6"], ["i", "7"], ["j", "8"]],
  #    [["k", "9"], ["l", "10"], ["m", "11"], ["n", "12"]]]    

<强>解释

以上示例的步骤:

c

in the PDO scheme there传递a的第一个元素并设置块变量a = [["8c", "1"],["d","2"],["e","3"],["f","4"]]

a.map { |_,e| Integer(e) }
  #=> [1, 2, 3, 4]

然后:

Integer(e)

我选择使用e.to_i而不是e,以便在Integer("cat") #=> ArgumentError: invalid value for Integer(): "cat" 不是整数的字符串表示形式时引发异常:

"cat".to_i
   #=> 0

,而:

Integer

实际上,c会在进行转换之前执行数据检查。

def pull_numbers(h) h.values.flatten.each_slice(2).map { |_,e| Integer(e) } end 的其他两个元素的处理方式相似。

<强>变体

可以写一下:

com.badlogic.gdx.math.Intersectoroverlaps(Rectangle r1, Rectangle r2)

答案 4 :(得分:2)

以下是执行此操作的一种方法:

h = { 
  a: [ ["c", "1"],["d","2"],["e","3"],["f","4"] ], 
  b: [ ["g","5"],["h","6"],["i","7"],["j","8"] ], 
  c: [ ["k","9"],["l","10"],["m","11"],["n","12"] ]
}

h.values.flatten(1).collect(&:last).map(&:to_i)
#=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

或者你可以这样做:

h.to_a.flatten.select { |x| x =~ /\d/ }.map(&:to_i)

答案 5 :(得分:2)

使用 Array#transpose 方法的简短替代方法:

&#xA;&#xA;
 &gt; h.values.flatten(1).transpose.last&#XA; =&GT; [“1”,“2”,“3”,“4”,“5”,“6”,“7”,“8”,“9”,“10”,“11”,“12”]& #xA;&#xA; #with to number conversion&#xA;&gt; h.values.flatten(1).transpose.last.map(安培;:to_i)&#XA; =&GT; [1,2,3,4,5,6,7,8,9,10,11,12]&#xA;  
&#xA;&#xA;

基准

&#xA;&#xA;
 需要'基准'&#xA;&#xA; h = {&#xA; a:[[“c”,“1”],[“d”,“2”],[“e”,“3”],[“f”,“4”],&#xA; b:[[“g”,“5”],[“h”,“6”],[“i”,“7”],[“j”,“8”]],&#xA; c:[[“k”,“9”],[“l”,“10”],[“m”,“11”],[“n”,“12”]]&#xA;}&# xA;&#xA; Benchmark.bm(10)do | x |&#xA; x.report(“transpose”)do&#xA; 1000.times {h.values.flatten(1).transpose.last.map(&amp;:to_i)}&#xA;端&#XA; x.report(“collect / map”)do&#xA; 1000.times {h.values.flatten(1).collect(&amp;:last).map(&amp;:to_i)}&#xA;端&#XA; x.report(“regexp”)do&#xA; 1000.times {h.values.flatten.select {| v | v.match(/ \ d /)}。map(&amp;:to_i)}&#xA;端&#XA; x.report(“Integer”)do&#xA; 1000.times {h.values.flat_map {| a | a.map {| _,e |整数(e)}}}&#xA;端&#XA末端&#XA;  
&#XA;&#XA;

<强>结果

&#XA;&#XA;
 用户系统总实数&#xA;转置0.000000 0.000000 0.000000(0.006971)&#xA; collect / map 0.010000 0.000000 0.010000(0.007490)&#xA; regexp 0.030000 0.010000 0.040000(0.031939)&#xA;整数0.010000 0.000000 0.010000( 0.006832)&#XA;  
&#XA;