Warm tip: This article is reproduced from serverfault.com, please click

Deeply compact nested hash in ruby?

发布于 2016-10-27 16:29:57

Given the following hash structure...

{
  a: nil,
  b: [],
  c: {c1: {c2: nil}},
  d: [{d1: "Value!"}],
  e: "Value!",
  f: {f1: {f2: nil, f3: "Value!"}}
}

I'd like to be able to return...

{
  d: [{d1: "Value!"}],
  e: "Value!",
  f: {f1: {f3: "Value!"}}
}

So the rules would be
1) Remove any key that points to a nil, {}, or [] value
2) Remove any key that leads to value which points to an empty value (example c: from the original hash)
3) Preserve the outer key if one or more inner keys point to a non empty value, but remove inner keys that point to an empty value. (see f: and notice that f2: is removed)

Any help would be appreciated!

Questioner
cheeseandpepper
Viewed
0
tadman 2016-10-28 02:24:32

You could have some fun with monkey-patching the core classes involved:

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

It's an unusual thing to want to do, but if you do need it done writing a method like crush might help.