che*_*per 3 ruby hash ruby-on-rails
给定以下哈希结构...
{
a: nil,
b: [],
c: {c1: {c2: nil}},
d: [{d1: "Value!"}],
e: "Value!",
f: {f1: {f2: nil, f3: "Value!"}}
}
Run Code Online (Sandbox Code Playgroud)
我希望能够回来...
{
d: [{d1: "Value!"}],
e: "Value!",
f: {f1: {f3: "Value!"}}
}
Run Code Online (Sandbox Code Playgroud)
因此,规则将是
1) 删除任何指向nil、{}或[]值的键
2) 删除导致指向空值的值的任何键(c:原始哈希的示例)
3) 如果存在一个或多个,则保留外部键内部键指向非空值,但删除指向空值的内部键。(请参阅f:并注意f2:已删除的内容)
任何帮助,将不胜感激!
您可以通过猴子修补所涉及的核心类来获得一些乐趣:
class Object
def crush
self
end
end
class Array
def crush
r = map(&:crush).compact
r.empty? ? nil : r
end
end
class Hash
def crush
r = each_with_object({ }) do |(k, v), h|
if (_v = v.crush)
h[k] = _v
end
end
r.empty? ? nil : r
end
end
Run Code Online (Sandbox Code Playgroud)
这是一件不寻常的事情,但如果你确实需要这样做,那么编写一个类似的方法crush可能会有所帮助。
这应该是一个适用于嵌套数组和哈希的一次性操作:
CRUSHABLE = [nil, [], {}].freeze
def crush(thing)
if thing.is_a?(Array)
thing.each_with_object([]) do |v, a|
v = crush(v)
a << v unless CRUSHABLE.include?(v)
end
elsif thing.is_a?(Hash)
thing.each_with_object({}) do |(k,v), h|
v = crush(v)
h[k] = v unless CRUSHABLE.include?(v)
end
else
thing
end
end
Run Code Online (Sandbox Code Playgroud)