递归地从对象中删除属性

时间:2013-12-09 13:30:07

标签: ruby-on-rails ruby json

我有一个JSON字符串,我想从某些值中删除它。问题是JSON对象可以包含子对象,如果它们存在,我想剥离相同类型的值(基于键)。

例如,我得到了这个:

{
    Title: "test",
    Created: "2013-01-01",
    ID: 1
    Child: {
        Title: "Test 2",
        Created: "2013-01-02",
        ID: 2,
        RandomName: {
            Title: "Test 3",
            Created: "2013-01-05",
            ID:3
        }
    }
}

我想从对象和所有子对象中删除“Created”键。有没有一种简单的方法可以在Ruby中实现这一目标?

3 个答案:

答案 0 :(得分:1)

您可以编写一个以递归方式调用嵌套元素的帮助程序(例如,假设您将JSON解析为哈希)

def remove_recursive(hash)
  hash.each do |key, value|
    hash.delete(key) if key == "Created"
    remove_recursive(hash[key]) if hash[key].kind_of?(Hash)
  end
end

答案 1 :(得分:1)

如果您不想为此设置方法,可以使用proc进行此操作。

require 'json'

json_string = '{
    "Title": "test",
    "Created": "2013-01-01",
    "ID": 1,
    "Child": {
        "Title": "Test 2",
        "Created": "2013-01-02",
        "ID": 2,
        "RandomName": {
            "Title": "Test 3",
            "Created": "2013-01-05",
            "ID": 3
        }
    }
}'


without_fields = proc do |h, *fields|
  h = h.reject {|k,_| fields.include?(k) }
  h.each do |k, v|
    if v.is_a?(Hash)
      h[k] = without_fields.call(v, *fields)
    end
  end
  h
end

json_obj = JSON.load(json_string)
cleaned_obj = without_fields.call(json_obj, 'Created')
JSON.dump(cleaned_obj)
# => "{\"Title\":\"test\",\"ID\":1,\"Child\":{\"Title\":\"Test 2\",\"ID\":2,\"RandomName\":{\"Title\":\"Test 3\",\"ID\":3}}}"

答案 2 :(得分:1)

基于托比亚斯'回答,我修改了代码以支持子数组等。请注意,我对Ruby很新,所以我不确定这是100%完成。

keysToRemove参数是一个数组,其中包含我要删除的键的名称。

def remove_recursive(hash, keysToRemove)
    if hash.kind_of?(Array)
      hash.each do |h|
        remove_recursive(h, keysToRemove)
      end
    elsif hash.kind_of?(Hash)
      hash.each do |key, value|
        if keysToRemove.include?(key)
          hash.delete(key)
        else
          remove_recursive(hash[key], keysToRemove)
        end
      end
    end
  end