我需要实施Array#flatten
。此实现删除所有嵌套数组:
a = [1, 2, [3, [4, 5]]]
def my_flatten(arr)
arr.reduce([]) do |result, item|
item.is_a?(Array) ? result + my_flatten(item) : result << item
end
end
my_flatten(a) #=> [1, 2, 3, 4, 5]
提示如何实施此类行为
a.flatten(1) #=> [1, 2, 3, [4, 5]]
答案 0 :(得分:3)
引入一个参数来指定最大深度(默认为nil
)和一个跟踪当前深度的参数(初始调用为0,然后在每次递归调用时递增1):
def my_flatten(arr, max_depth = nil, current_depth = 0)
arr.reduce([]) do |result, item|
item.is_a?(Array) && (max_depth.nil? || current_depth < max_depth) ?
result + my_flatten(item, max_depth, current_depth + 1) : result << item
end
end
如果您认为这更具可读性,可以将?:
替换为if/else
:
def my_flatten(arr, max_depth = nil, current_depth = 0)
arr.reduce([]) do |result, item|
if item.is_a?(Array) && (max_depth.nil? || current_depth < max_depth)
result + my_flatten(item, max_depth, current_depth + 1)
else
result << item
end
end
end
现在返回预期结果:
my_flatten(a) #=> [1, 2, 3, 4, 5]
my_flatten(a, 1) #=> [1, 2, 3, [4, 5]]
答案 1 :(得分:2)
我很长一段时间创造了类似的东西。这是gist link。
来自要点的代码:
<rule>
<condition type="scheme" operator="equal">^http$</condition>
<from>/(.*)</from>
<set type="status">307</set>
<set type="response-header" name="Location">https://something.com/$1</set>
<to last="true">null</to>
</rule>
希望有所帮助。
答案 2 :(得分:1)
你也可以像这样使用Proc
。
class Array
def my_flatten(level = nil)
p = ->(arr, exp, lvl) do
arr.each { |val| Array === val && (!level || lvl < level) ? p.(val, exp, lvl+1) : exp << val }
exp
end
p.(self, [], 0)
end
end
a = [1, 2, [3, [4, 5]]]
p a.my_flatten
# => [1, 2, 3, 4, 5]
p a.my_flatten(0)
# => [1, 2, [3, [4, 5]]]
p a.my_flatten(1)
# => [1, 2, 3, [4, 5]]
p a.my_flatten(2)
# => [1, 2, 3, 4, 5]