我希望从哈希中删除具有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}
答案 0 :(得分:8)
尝试怎么样:
hash = article.attributes.select {|k, v| v }
如果值为false
或nil
,则该属性将被忽略。
如果您想保留错误值并且只消除nil
,则可以运行:
hash = article.attributes.select {|k, v| !v.nil? }
答案 1 :(得分:6)
如果您使用的是Ruby> = 2.4.6,则可以使用compact
。
https://apidock.com/ruby/v2_4_6/Hash/compact
示例:
hash = {:foo => nil, :bar => "bar"}
=> {:foo=>nil, :bar=>"bar"}
hash.compact
=> {:bar=>"bar"}
hash
=> {:foo=>nil, :bar=>"bar"}
还有compact!
会删除nil个值,或者如果哈希中的任何值都不为nil(从版本> = 2.5.5开始),则为nil。
https://apidock.com/ruby/v2_4_6/Hash/compact%21
示例:
hash
=> {:foo=>nil, :bar=>"bar"}
hash.compact!
=> {:bar=>"bar"}
hash
=> {:bar=>"bar"}
hash.compact!
=> nil
答案 2 :(得分:5)
您可以从散列中删除所有nil
值,即“h”:
h.delete_if { |k, v| v.nil? }
你也可以使用这个删除空值:
h.delete_if { |k, v| v.nil? || v.empty? }
答案 3 :(得分:1)
在我的情况下,我使用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
答案 4 :(得分:0)
给定的输入是有效的JSON,问题有JSON标记,所以我想提供一个通用的解决方案来解决JSON对象中递归消除密钥的问题,无论它们出现在哪里,无论输入JSON是什么也许。
解决方案是用一种新的面向JSON的编程语言jq编写的,但即使你不能使用jq,解决方案也是如此简洁和优雅,以至于它可能会建议用你选择的语言实现一般问题。 / p>
这是 - 一个单行:
walk( if type == "object" then with_entries( select(.value != null) ) else . end)
这预先假定jq版本1.5(见https://stedolan.github.io/jq/)。
如果你有旧版本的jq,可以很容易地添加walk / 1的定义。 (参见例如Transforming the name of key deeper in the JSON structure with jq)