根据key =>删除嵌套哈希值值

时间:2015-02-02 22:31:07

标签: ruby json hash

我有这个哈希:

response = '{"librairies":[{"id":1,"books":[{"id":1,"qty":1},{"id":2,"qty":3}]},{"id":2,"books":[{"id":1,"qty":0},{"id":2,"qty":3}]}]}'

我想删除每个图书馆,其中至少有一本图书数量为空。

例如,有了这个response,我希望得到这个回报:

'{"librairies":[{"id":1,"books":[{"id":1,"qty":1},{"id":2,"qty":3}]}]}'

我试过这个:

parsed = JSON.parse(response)

parsed["librairies"].each do |library|
  library["books"].each do |book|
    parsed.delete(library) if book["qty"] == 0
  end
end

但是这会返回完全相同的response哈希值,而不会删除第二个库(id => 2)。

2 个答案:

答案 0 :(得分:2)

您可以将Array#delete_ifEnumerable#any?用于此

# Move through each array element with delete_if
parsed["librairies"].delete_if do |library|
  # evaluates to true if any book hash in the library
  # has a "qty" value of 0
  library["books"].any? { |book| book["qty"] == 0 }
end

希望这有帮助

答案 1 :(得分:0)

为避免更改哈希parsed,您可以执行以下操作。

首先,让我们格式化parsed,以便我们可以看到我们正在处理的内容:

parsed = { "libraries"=>[ { "id"=>1,
                            "books"=>[ { "id"=>1, "qty"=>1 },
                                       { "id"=>2, "qty"=>3 } ]
                          },
                          { "id"=>2,
                            "books"=>[ { "id"=>1, "qty"=>0 },
                                       { "id"=>2, "qty"=>3 } ]
                          }
                        ]
         }

稍后我想表明在创建新哈希时parsed没有被更改。一种简单的方法是在parsed之前和之后计算哈希码,并查看它是否发生变化。 (虽然不是100%肯定不同的哈希值不会有相同的哈希码,但这里不会失去睡眠。)

parsed.hash
  #=> 852445412783960729

我们首先需要制作一个"深拷贝" parsed的{​​{1}},以便对副本的更改不会影响parsed。一种方法是使用Marshal模块:

new_parsed = Marshal.load(Marshal.dump(parsed))

我们现在可以根据需要修改副本:

new_parsed["libraries"].reject! { |h| h["books"].any? { |g| g["qty"].zero? } }
  #=> [ { "id"=>1,
  #       "books"=>[ { "id"=>1, "qty"=>1 },
  #                  { "id"=>2, "qty"=>3 }
  #                ]
  #     }
  #   ]

new_parsed # => { "libraries"=>[ { "id"=>1,
                                   "books"=>[ { "id"=>1, "qty"=>1},
                                              { "id"=>2, "qty"=>3}
                                            ]
                                 }
                               ]
                } 

我们确认原始哈希没有改变:

parsed.hash
  #=> 852445412783960729