如何在这个json结构中获得ruby的哈希联合

时间:2015-07-26 02:30:38

标签: ruby-on-rails ruby

下面是json我从ruby哈希翻译过来,为了便于使用hash.to_json来表示这个问题。请注意密钥range是如何重复的,因为嵌套文档中的值不同。如何合并范围,以便对于weight键,"gt": 2232, "lt": 4444都属于范围内的一个哈希键权重。在红宝石中是否存在某种“紧凑”哈希的联合或崩溃方法?

{
    "must": [
        {
            "match": {
                "status_type": "good"
            }
        },
        {
            "range": {
                "created_date": {
                    "lte": 43252
                }
            }
        },
        {
            "range": {
                "created_date": {
                    "gt": "42323"
                }
            }
        },
        {
            "range": {
                "created_date": {
                    "gte": 523432
                }
            }
        },
        {
            "range": {
                "weight": {
                    "gt": 2232
                }
            }
        },
        {
            "range": {
                "weight": {
                    "lt": 4444
                }
            }
        }
    ],
    "should": [
        {
            "match": {
                "product_age": "old"
            }
        }
    ]
}

想要将上述内容更改为:

{
    "must": [
        {
            "range": {
                "created_date": {
                    "gte": 523432,
                    "gt": "42323"
                }
            }
        },
        {
            "range": {
                "weight": {
                    "gt": 2232,
                    "lt": 4444
                }
            }
        }
    ],
    "should": [
        {
            "match": {
                "product_age": "old"
            }
        }
    ]
}

1 个答案:

答案 0 :(得分:1)

我不知道内置的方法来处理这样的事情,但是你可以编写一个类似这样的方法:

def collapse(array, key)
  # Get only the hashes with :range
  to_collapse = array.select { |elem| elem.has_key? key }

  uncollapsed = array - to_collapse

  # Get the hashes that :range points to
  to_collapse = to_collapse.map { |elem| elem.values }.flatten

  collapsed = {}

  # Iterate through each range hash and their subsequent subhashes.
  # Collapse the values into the collapsed hash as necessary
  to_collapse.each do |elem|
    elem.each do |k, v|
      collapsed[k] = {} unless collapsed.has_key? k
      v.each do |inner_key, inner_val|
        collapsed[k][inner_key] = inner_val
      end
    end
  end
  [uncollapsed, collapsed].flatten
end

hash[:must] = collapse hash[:must], :range

请注意,这是一个特定的解决方案,主要适用于所提出的问题。它仅适用于此处指定的散列/数组深度。您可以编写一个递归解决方案,该解决方案可以在任何更深层次上工作,并且需要更多工作。