Arrays 如何从散列中创建数组,用整数替换所有键和值

Arrays 如何从散列中创建数组,用整数替换所有键和值,arrays,ruby,hash,Arrays,Ruby,Hash,我有一个杂烩: a = {"0" => ["2", "3"], "1" => "4", "3" => "5"} 我需要一个函数从中生成一个数组: a = [[2, 3], 4, nil, 5] 有什么简单的方法可以做到这一点吗?你正在寻找的方法,尽管你不会得到零: a = {"0" => ["2", "3"], "1" => "4", "3" => "5"} def deep_map(h) h.map{|i| i.is_a?(String) ? i.t

我有一个杂烩:

a = {"0" => ["2", "3"], "1" => "4", "3" => "5"}
我需要一个函数从中生成一个数组:

a = [[2, 3], 4, nil, 5]
有什么简单的方法可以做到这一点吗?

你正在寻找的方法,尽管你不会得到零:

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] 

首先,我们将从0到最大键值的范围设为整数 然后,对于每个数字,我们在相应的键处获取a中的值。 如果该值是一个数组,则将其转换为整数数组 如果不是,则将其转换为整数,除非它为false或nil

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的更好版本

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

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

结果与样本输入一致。我没有测试任何其他案例:

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]

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

如果我们简化了将散列键和值转换为数字并添加缺少的键的问题,那么您可以借助Rails的主动支持散列扩展执行以下操作:

# Below require needed only if code is not being used in Rails app
require "active_support/core_ext/hash"

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

p a.deep_merge(a) {|_,v,_| v.to_i rescue v.map(&:to_i)}
   .transform_keys(&:to_i)
   .tap { |h| h.reverse_update (h.keys.min..h.keys.max).zip([nil]).to_h }
   .sort {|a,b| a <=> b}  # Not really needed
   .to_h                  # Not really needed

#=> {0=>[2, 3], 1=>4, 2=>nil, 3=>5}

我将字符串转换为单独的方法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]

不清楚。特别是,零来自哪里?为什么不是[nil、[2,3]、4,nil、5]或[2,3]、4,nil、5,nil]或[2,3]、4,nil、5,nil、nil]?请查看我的更新回答欢迎使用堆栈溢出。我们希望您已经尝试过,并且尝试了很多次,当您在尝试了很多次之后感到筋疲力尽时,您会问,您将向我们展示您尝试过的内容的摘要版本,并解释为什么它不起作用。我们希望看到您为解决此问题而编写的最小代码,以及为什么它不起作用。您不需要UPD:,我们可以看到您所做的更改。读取,您可能会将哈希a或数组h、字符串i或fixnum s命名,从而混淆您的读者。另外,将一个变量设置为哈希值,然后重用同一个变量来指向数组通常不是一个好的做法。我认为0..a.size的大小与预期数组的大小匹配只是巧合。如果原始散列中跳过的元素数是两个怎么办?@sawa你是对的,不知道我在想什么,修正了!不鼓励只使用代码的答案,就像完全不使用代码的答案一样。请解释为什么这是可用的,和/或正确的答案。你不仅在回答OP的问题,而且在帮助未来的任何人寻找同一问题的解决方案。教他们钓鱼,只是不要为了解决这个问题而扔掉一条鱼。为什么假定转换为整数后的最小键为0,而计算最大键?没错,OP的示例中最小的键是0,但这只是一个示例。2.您可以通过将第二行替换为0..a.max_by&:to_i.map{v|并将下面的行替换为x=a[v]来简化。注意[1,12,3]。minmax=>[1,3]。你需要a.keys.minmax\u by&:to\I。@AndreyDeineko似乎有人在这个相当有缺陷的问题上系统性地否决了所有答案。系统将捕获那些系统性地否决他人的人。有时人们会得到一整袋否决票,并决定将他们扔到某物上。我没有否决投票,但你的答案是不正确的,不是吗返回strings@BjörnNilsson你完全正确,谢谢。固定版本不是很优雅,真的很难看,但它符合OPs规范。我编辑了我的答案。如果a={0'=>'1',99'=>'2',你的方法将返回[1,nil,nil]我不相信OP想要的。更一般地说,我们应该因为1x1等于1而推断出nxn等于1吗?
# Below require needed only if code is not being used in Rails app
require "active_support/core_ext/hash"

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

p a.deep_merge(a) {|_,v,_| v.to_i rescue v.map(&:to_i)}
   .transform_keys(&:to_i)
   .tap { |h| h.reverse_update (h.keys.min..h.keys.max).zip([nil]).to_h }
   .sort {|a,b| a <=> b}  # Not really needed
   .to_h                  # Not really needed

#=> {0=>[2, 3], 1=>4, 2=>nil, 3=>5}
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]