从哈希中删除 nil 值

问题描述 投票:0回答:5

我希望从哈希中删除具有

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&#160;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}
ruby json hash
5个回答
31
投票

您可以使用

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

11
投票

尝试一下怎么样:

hash = article.attributes.select {|k, v| v }

如果值为

false
nil
,则该属性将被忽略。

如果你想保留错误值并只消除

nil
,你可以运行:

hash = article.attributes.select {|k, v| !v.nil? }

8
投票

您可以从哈希值(即“h”)中删除所有

nil
值:

h.delete_if { |k, v| v.nil? }

您也可以使用它来删除空值:

h.delete_if { |k, v| v.nil? || v.empty? }

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

0
投票

给定的输入是有效的 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 结构中更深入地转换键的名称

© www.soinside.com 2019 - 2024. All rights reserved.