简体   繁体   English

从哈希中删除 nil 值

[英]Remove nil values from hash

I am looking to remove keys from hash that have nil value.我希望从散列中删除具有nil值的键。 article is a class storing each article, and attributes method stores the article as hash. article是存储每篇文章的类, attributes方法将文章存储为哈希。

Expected Result:预期结果:

{"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}]}]}

Looking to remove null values from the above output.希望从上述输出中删除空值。

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

The result is as below:结果如下:

{"0":null,"1":null,"2":null,"3":null,"4":null,"5":null,"6":null,"7":null,"8":null,"9":null,"10":null}

How about trying:试试怎么样:

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

If the value is false or nil , the attribute will be ignored.如果值为falsenil ,则该属性将被忽略。

If you want to keep the false value and only eliminate nil , you could run:如果您想保留 false 值并只消除nil ,您可以运行:

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

If you're on Ruby >= 2.4.6, you can use compact .如果您使用 Ruby >= 2.4.6,则可以使用compact

https://apidock.com/ruby/v2_4_6/Hash/compact https://apidock.com/ruby/v2_4_6/Hash/compact

Example:例子:

hash = {:foo => nil, :bar => "bar"}
=> {:foo=>nil, :bar=>"bar"}
hash.compact
=> {:bar=>"bar"}
hash
=> {:foo=>nil, :bar=>"bar"}

There's also compact!还有compact! which removes nil values, or nil if no values in the hash were nil (from version >= 2.5.5).它删除 nil 值,如果哈希中没有值为零(从版本 >= 2.5.5),则删除 nil。

https://apidock.com/ruby/v2_4_6/Hash/compact%21 https://apidock.com/ruby/v2_4_6/Hash/compact%21

Example:例子:

hash
=> {:foo=>nil, :bar=>"bar"}
hash.compact!
=> {:bar=>"bar"}
hash
=> {:bar=>"bar"}
hash.compact!
=> nil

You can remove all the nil values from a hash namely "h":您可以从散列中删除所有nil值,即“h”:

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

and you can use this one to remove empty values, too:你也可以使用这个来删除空值:

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

In my case I use refinements to Hash class就我而言,我对 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

The given input is valid JSON, and the question has the JSON tag, so I'd like to offer a generic solution to the problem of recursively eliminating keys in JSON objects, wherever they occur, and no matter what the input JSON may be.给定的输入是有效的 JSON,问题有 JSON 标签,所以我想提供一个通用的解决方案来解决递归消除 JSON 对象中的键的问题,无论它们出现在何处,无论输入 JSON 可能是什么。

The solution is written in a new JSON-oriented programming language, jq, but even if you cannot use jq, the solution is so brief and elegant that it may suggest an implementation to the general problem in your language of choice.该解决方案是用一种新的面向 JSON 的编程语言 jq 编写的,但即使您不能使用 jq,该解决方案也非常简洁优雅,它可能会建议您使用所选语言对一般问题进行实现。

Here it is - a one-liner:这是 - 一个单线:

walk( if type == "object" then with_entries( select(.value != null) ) else . end)

This presupposes jq version 1.5 (see https://stedolan.github.io/jq/ ).这以 jq 1.5 版为前提(参见https://stedolan.github.io/jq/ )。

If you have an older version of jq, the definition of walk/1 can easily be added.如果您有旧版本的 jq,则可以轻松添加 walk/1 的定义。 (See eg Transforming the name of key deeper in the JSON structure with jq ) (参见例如使用 jq 在 JSON 结构中更深入地转换密钥的名称

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM