最初我打算做以下事情:
arr = [[1,2],[3,4]]
new_arr =
arr.map do |sub_arr|
sub_arr.map do |x|
x+1
end
end
p new_arr
输出:
[[2,3],[4,5]]
但后来我试图通过“链接”调查员来缩短它:
arr.map.map{|x| x+1}
然后它会给出错误to_ary method missing
我通过
调试了它arr.each.each{|x| p x}
输出:
[1,2]
[3,4]
,这是原始数组,只取消了一次。
如何链接两个地图/每个枚举器,以便将枚举器分为2个(或更多)级别?或者它必须在块中?
更新
经过一些搜索,显然链obj.Enumerator.Enumerator.Enumerator...
只列举一次obj,只有1级深度。为了更深入,需要阻止。我制定了简单的代码,将字符串转换为块(Proc / Lambda;类似于符号到块但更多地使用;更像是函数语法),以便避免使用块。有人有类似的代码String#to_proc
,但我找不到它,x,y
中的内容不符合我的口味。我使用$0,$1,$2,...
示例代码(前面的示例将写为):
arr = [[1,2],[3,4]]
new_arr = arr.map(&'[$0+1,$1+1]')
p new_arr
我稍后会将原始代码推送到github。如果你想在此之前看到它,你可以使用聊天与我联系,因为我真的拖延:)
答案 0 :(得分:3)
听起来像递归的工作:
def zipper(args)
args[0].respond_to?(:each) ? args.map{|a| zipper(a)} : args.map{|i| i+1}
end
zipper([[1,2],[3,4]])
# => [[2, 3], [4, 5]]
zipper([[[1,2],[3,4]],[5,6]])
# => [[[2, 3], [4, 5]], [6, 7]]
答案 1 :(得分:3)
也许你需要一个map
,你只想在叶子上应用:
module Enumerable
def nested_map &block
map{|e|
case e
when Enumerable
e.nested_map(&block)
else
block.call(e)
end
}
end
end
p [[1,2], [3,4]].nested_map(&:succ)
#=> [[2, 3], [4, 5]]
或map
仅适用于n
级嵌套结构。
module Enumerable
def deep_map level, &block
if level == 0
map(&block)
else
map{|e| e.deep_map(level - 1, &block)}
end
end
end
p [[1,2], [3,4]].deep_map(1, &:succ)
#=> [[2, 3], [4, 5]]
答案 2 :(得分:2)
arr.map {|x| x.map(&:succ)} #=> [[2, 3], [4, 5]]
答案 3 :(得分:0)
为了通过只编写一次x+1
来做到这一点,你需要将它放在一个块中。否则,你可以这样做:
new_arr = arr.map {| x,y | [x + 1,y + 1]}
或者,如果你坚持,你可以这样做:
new_arr = arr.flatten(1).map {| x | X + 1} .each_slice(2).to_a
答案 4 :(得分:0)
就我个人而言,我会像下面两个选项中的一个一样编写它并完成它:
arr.map { |a| a.map(&:next) }
#=> [[2, 3], [4, 5]]
arr.map { |x, y| [x.next, y.next] }
#=> [[2, 3], [4, 5]]