我希望从哈希中删除具有
nil
值的键。 article
是存储每篇文章的类,attributes
方法将文章存储为散列。
预期结果:
{"articles":[{"results":[{"author":null,"title":"Former bar manager jailed for preying on homeless 14-year-old girl","summary":"<p><img src=\"http://images.theage.com.au/2015/08/24/6790912/Thumbnail999662740gisd08image.related.thumbnail.320x214.gj68pg.png1440386418031.jpg-90x60.jpg\" width=\"90\" height=\"60\" style=\"float:left;margin:4px;border:0px\"/></p>A man who preyed on a 14-year-old girl he came across living on the streets of Wodonga has been jailed for nine months.","images":null,"source":null,"date":"Mon, 24 Aug 2015 03:20:21 +0000","guid":"<guid isPermaLink=\"false\">gj68pg</guid>","link":"http://www.theage.com.au/victoria/former-bar-manager-jailed-for-preying-on-homeless-14yearold-girl-20150824-gj68pg.html","section":null,"item_type":null,"updated_date":null,"created_date":null,"material_type_facet":null,"abstract":null,"byline":null,"kicker":null}]}]}
希望从上述输出中删除空值。
def attributes
hash = {
"author" => @author,
"title" => @title,
"summary" => @summary,
"images" => @images,
"source" => @source,
"date" => @date
}
hash = {}
count = 0
article.attributes.each do |key,value|
if value == nil
hash[count] = article.attributes.delete(key)
count += 1
end
end
hash.to_json
结果如下:
{"0":null,"1":null,"2":null,"3":null,"4":null,"5":null,"6":null,"7":null,"8":null,"9":null,"10":null}
您可以使用
compact
。
https://ruby-doc.org/core-2.7.0/Hash.html#method-i-compact
示例:
hash = {:foo => nil, :bar => "bar"}
=> {:foo=>nil, :bar=>"bar"}
hash.compact
=> {:bar=>"bar"}
hash
=> {:foo=>nil, :bar=>"bar"}
还有
compact!
可以删除 nil 值,或者如果哈希中没有值为零则返回 nil
。
https://ruby-doc.org/core-2.7.0/Hash.html#method-i-compact-21
示例:
hash
=> {:foo=>nil, :bar=>"bar"}
hash.compact!
=> {:bar=>"bar"}
hash
=> {:bar=>"bar"}
hash.compact!
=> nil
尝试一下怎么样:
hash = article.attributes.select {|k, v| v }
如果值为
false
或 nil
,则该属性将被忽略。
如果你想保留错误值并只消除
nil
,你可以运行:
hash = article.attributes.select {|k, v| !v.nil? }
您可以从哈希值(即“h”)中删除所有
nil
值:
h.delete_if { |k, v| v.nil? }
您也可以使用它来删除空值:
h.delete_if { |k, v| v.nil? || v.empty? }
在我的例子中,我使用 Hash 类的改进
module HashUtil
refine Hash do
# simple but can not adapt to nested hash
def squeeze
select{|_, v| !v.nil? }
end
# complex but can adapt to nested hash
def squeeze_deep
each_with_object({}) do |(k, v), squeezed_hash|
if v.is_a?(Hash)
squeezed_hash[k] = v.squeeze
else
squeezed_hash[k] = v unless v.nil?
end
end
end
end
end
class Article
using HashUtil
def attributes
hash = {
"author" => @author,
"title" => @title,
"summary" => @summary,
"images" => @images,
"source" => @source,
"date" => @date
}
hash.squeeze
end
end
给定的输入是有效的 JSON,并且问题具有 JSON 标签,因此我想提供一个通用的解决方案来解决递归消除 JSON 对象中的键的问题,无论它们出现在何处,也无论输入 JSON 是什么。
该解决方案是用一种新的面向 JSON 的编程语言 jq 编写的,但即使您不能使用 jq,该解决方案也非常简洁和优雅,以至于它可能会建议您使用您选择的语言来实现一般问题。
这是——一句单行话:
walk( if type == "object" then with_entries( select(.value != null) ) else . end)
这以 jq 版本 1.5 为前提(请参阅 https://stedolan.github.io/jq/)。
如果您有旧版本的 jq,可以轻松添加 walk/1 的定义。 (参见例如使用 jq 在 JSON 结构中更深入地转换键的名称)