如何使用整数替换所有键和值来创建数组

时间:2016-01-23 19:41:51

标签: arrays ruby hash

我有一个哈希:

a = {"0" => ["2", "3"], "1" => "4", "3" => "5"}

我需要一个函数来从中创建一个数组:

a = [[2, 3], 4, nil, 5]

有没有简单的方法可以做到这一点?

6 个答案:

答案 0 :(得分:4)

min, max = a.keys.minmax_by(&:to_i)

min.upto(max).map do |key|
  a[key].respond_to?(:map) ? a[key].map(&:to_i) : a[key].to_i if a[key]
end # => [[2, 3], 4, nil, 5]

答案 1 :(得分:4)

首先我们设置一个从0到最大键值的范围(作为整数) 然后,对于每个数字,我们在" a"中获取值。在相应的钥匙。 如果值是数组,我们将其转换为整数数组 如果没有,将其转换为整数(除非它是假或零)。

a = {"0" => ["2", "3"], "1" => "4", "3" => "5"}
a = (0..(a.keys.map(&:to_i).max)).map do |v|
  x = a[v.to_s]
  x.is_a?(Array) ? x.map(&:to_i) : (x && x.to_i)
end

可以处理最小密钥的更好版本> " 0"

a = a.values_at(*Range.new(*a.keys.minmax_by(&:to_i))).map do |v|
  v.is_a?(Array) ? v.map(&:to_i) : (v && v.to_i)
end

a
=> [[2, 3], 4, nil, 5]

minmax返回一个数组,我们将其分解为Range.new的参数 然后,我们将该范围分解为values_at的参数。

[*Range.new(*["2","8"])]
=> ["2", "3", "4", "5", "6", "7", "8"]

答案 2 :(得分:1)

我不确定让你拥有的数组作为最终输出是否真的有意义,因为现在你不确定哪个元素对应于哪个问题。

如果我们简化您要将哈希键和值转换为数字并添加缺失键的问题,那么您可以在Rails的Active Support Hash扩展的帮助下执行以下操作:

{{1}}

答案 3 :(得分:0)

你正在寻找Hash.values虽然你不会在那里得到那个:

a = {"0" => ["2", "3"], "1" => "4", "3" => "5"}
def deep_map(h)
  h.map{|i| i.is_a?(String) ? i.to_i : deep_map(i)}
end
deep_map (a.values)

给出:

[[2, 3], 4, 5] 

答案 4 :(得分:0)

样本输入结果正常。我没有测试任何其他情况:

a = {"0" => ["2", "3"], "1" => "4", "3" => "5"}

('0'..a.size.to_s).map do |i| 
  v = ([a[i]].flatten.map { |i| i && i.to_i })
  v.size == 1 ? v[0] : v
end
# => [[2, 3], 4, nil, 5]

答案 5 :(得分:0)

我将字符串转换为单独的方法(fixnumify),因为它似乎不是问题的基本要素:

a = {"0" => ["2", "3"], "1" => "4", "3" => "5"}

def fixnumify(obj)
  case obj
  when Array then obj.map(&:to_i)
  when String then obj.to_i
  else obj
  end
end

from, to = a.keys.minmax_by(&:to_i)
  #=> [0, 3]
a.values_at(*from..to).map { |v| fixnumify(v) }
  #=> [[2, 3], 4, nil, 5]