【问题标题】:Ruby on Rails - How to delete entire parent json element if nested child has a certain valueRuby on Rails - 如果嵌套子元素具有特定值,如何删除整个父 json 元素
【发布时间】:2018-01-26 05:17:19
【问题描述】:

假设我有这个 JSON 示例:

[
{
    "id": "0001",
    "type": "donut",
    "name": "Cake",
    "ppu": 0.55,
    "batters":
        {
            "batter":
                [
                    { "id": "1001", "type": "Regular" },
                    { "id": "1002", "type": "Chocolate" }
                ]
        },
    "topping":
        [
            { "id": "5007", "type": "Powdered Sugar" },
            { "id": "5006", "type": "Chocolate with Sprinkles" },
            { "id": "5003", "type": "Chocolate" },
            { "id": "5004", "type": "Maple" }
        ]
},
{
    "id": "0002",
    "type": "donut",
    "name": "Raised",
    "ppu": 0.55,
    "batters":
        {
            "batter":
                [
                    { "id": "1005", "type": "DeleteMe" }
                ]
        },
    "topping":
        [
            { "id": "5001", "type": "None" },
            { "id": "5002", "type": "Glazed" }
        ]
},
{
    "id": "0003",
    "type": "donut",
    "name": "Old Fashioned",
    "ppu": 0.55,
    "batters":
        {
            "batter":
                [
                    { "id": "1001", "type": "Regular" },
                    { "id": "1002", "type": "Chocolate" }
                ]
        },
    "topping":
        [
            { "id": "5001", "type": "None" }
        ]
}
]

如何使用“DeleteMe”删除具有连击类型的整个元素?所以基本上,我希望删除整个元素 0002。我基本上想过滤掉所有带有batter type =“DeleteMe”的元素。

【问题讨论】:

  • 第 1 步)解析 JSON。步骤 2) 改为询问 Ruby 数据结构。步骤 3) 从更新的数据结构生成 JSON。

标签: ruby-on-rails json ruby


【解决方案1】:
json = '[
  {
    "id": "0001",
    "type": "donut",
    "name": "Cake",
    "ppu": 0.55,
    "batters":
      {
        "batter":
          [
            { "id": "1001", "type": "Regular" },
            { "id": "1002", "type": "Chocolate" }
          ]
      },
    "topping":
      [
        { "id": "5007", "type": "Powdered Sugar" },
        { "id": "5006", "type": "Chocolate with Sprinkles" },
        { "id": "5003", "type": "Chocolate" },
        { "id": "5004", "type": "Maple" }
      ]
  },
  {
    "id": "0002",
    "type": "donut",
    "name": "Raised",
    "ppu": 0.55,
    "batters":
      {
        "batter":
          [
            { "id": "1005", "type": "DeleteMe" }
          ]
      },
    "topping":
      [
        { "id": "5001", "type": "None" },
        { "id": "5002", "type": "Glazed" }
      ]
  },
  {
    "id": "0003",
    "type": "donut",
    "name": "Old Fashioned",
    "ppu": 0.55,
    "batters":
      {
        "batter":
          [
            { "id": "1001", "type": "Regular" },
            { "id": "1002", "type": "Chocolate" }
          ]
      },
    "topping":
      [
        { "id": "5001", "type": "None" }
      ]
  }
]'


parsed_data = JSON.parse(json)
result = parsed_data.delete_if do |data|
  data['batters']['batter'].detect { |batter| batter['type'] == 'DeleteMe' }
end

如果您希望输出为 json,您可以尝试 result.to_json

【讨论】:

    【解决方案2】:

    json 成为您的 JSON 数据结构。

    require 'json'
    
    arr = JSON.parse(json).
               reject { |h| h['batters']['batter'].any? { |g| g['type'] == "DeleteMe" } }
    

    如果需要,可以执行arr.to_json 来获取修改后的 JSON 对象。

    【讨论】:

      【解决方案3】:

      试试这个。

      json = 
      '[
      {
          "id": "0001",
          "type": "donut",
          "name": "Cake",
          "ppu": 0.55,
          "batters":
              {
                  "batter":
                      [
                          { "id": "1001", "type": "Regular" },
                          { "id": "1002", "type": "Chocolate" }
                      ]
              },
          "topping":
              [
                  { "id": "5007", "type": "Powdered Sugar" },
                  { "id": "5006", "type": "Chocolate with Sprinkles" },
                  { "id": "5003", "type": "Chocolate" },
                  { "id": "5004", "type": "Maple" }
              ]
      },
      {
          "id": "0002",
          "type": "donut",
          "name": "Raised",
          "ppu": 0.55,
          "batters":
              {
                  "batter":
                      [
                          { "id": "1005", "type": "DeleteMe" }
                      ]
              },
          "topping":
              [
                  { "id": "5001", "type": "None" },
                  { "id": "5002", "type": "Glazed" }
              ]
      },
      {
          "id": "0003",
          "type": "donut",
          "name": "Old Fashioned",
          "ppu": 0.55,
          "batters":
              {
                  "batter":
                      [
                          { "id": "1001", "type": "Regular" },
                          { "id": "1002", "type": "Chocolate" }
                      ]
              },
          "topping":
              [
                  { "id": "5001", "type": "None" }
              ]
      }
      ]';
      
      objArray = JSON.parse(json);
      
      objArray.reject! {|obj|
        obj['batters']['batter'].detect {|batter|
          batter['type'] == 'DeleteMe'
        }
      };
      
      result = objArray.to_json;
      

      我们在这里所做的是,我们首先将 json 字符串解析为一个对象数组,然后拒绝其中包含“DeleteMe”类型连击的那些元素。

      希望对您有所帮助。

      【讨论】:

        【解决方案4】:

        这样就可以了:

        JSON.parse(json).delete_if do |sweet| 
          sweet['batters']['batter'].detect { |batter| batter['type'] == 'DeleteMe' } 
        end
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-03-18
          • 1970-01-01
          • 2018-11-15
          相关资源
          最近更新 更多