【问题标题】:Only parse arrays with certain hashes using Hash#select and/or Array#select仅使用 Hash#select 和/或 Array#select 解析具有特定哈希值的数组
【发布时间】:2014-08-10 16:04:53
【问题描述】:

如何使用Hash#select 和/或Array#select 只解析包含{ "name": "sale", "value": "true" }products 数组?

直播应用:http://runnable.com/U-eWKpORZ5A644gK/array-hash-select-for-ruby-on-rails(见main_controller.rb

require 'hashie'

response = JSON.parse(@json_text)
mashie = Hashie::Mash.new(response)

@products = []
mashie.products.each do |product|
  product.extend Hashie::Extensions::DeepFetch

  product.name = product.deep_fetch(:name)

  @products << product
end
@products

【问题讨论】:

    标签: ruby-on-rails ruby arrays json hash


    【解决方案1】:

    使用select

    myarr = [{ "name" => "sale", "value" => "true" }, { "name" => "test", "value" => "true"}]
    myarr.select { |h| h["name"] == "sale" && h["value"] == "true" }
    => [{"name"=>"sale", "value"=>"true"}]
    

    在您的情况下,您将有一个看起来像这样的哈希(在解析 JSON 之后):

    response = {"productHeader" => {"totalHits" => 32090}, "products" => [{ "name" => "sale", "value" => "true" }, { "name" => "test", "value" => "true"}]}
    

    那么,你可以有这个代码:

    response = JSON.parse(@json_text)
    
    response["products"].select { |h| h["name"] == "sale" && h["value"] == "true" }.each do |filtered_response|
      # Do whatever you want with the filtered product
    end
    

    【讨论】:

    • 那么我应该将它与deep_fetch 或其他东西结合起来,因为这些值深深嵌套在products 中?另外,我如何只迭代 products 数组,这是真的?
    • 我认为您不需要任何deep_fetch。查看我的编辑。
    • 感谢您的光临,但可能存在误解。我不想改变 products 数组本身。我只想包含包含sale: trueproducts 数组。应跳过所有其他带有sale: falseproducts 数组。
    • 您没有更改数组。您只是在迭代满足条件的那些,并跳过其他的。如果你想改变数组,你可以使用select!
    • 另外,1)如何更好地组织多个条件,即。 sale: truesizes: Onesize?, 2) 请注意,当前的示例似乎打破了 Hashie::MashHashie::Extensions::DeepFetch 需要使代码看起来更漂亮。
    【解决方案2】:

    这甚至可以使用mashie

    @products = response['products'].select do |e|
      e.is_a? Hash \
      and (f = e['fields']).is_a? Array \
      and f.any? do |g|
        g.is_a? Hash \
        and g['name'] == 'sale' \
        and g['value'] == 'true'
      end
    end
    

    或者试试

    @products = response['products'].select do |e|
      e.is_a? Hash \
      and (f = e['fields']).is_a? Array \
      and f.any? do |g|
        g.is_a? Hash \
        and g['name'] == 'sale' \
        and g['value'] == 'true'
      end
    end.map{ |e| Hashie::Mash.new(e) }
    

    【讨论】:

    • 哇!相当光滑!知道为什么它会给出undefined method 'name'吗? runnable.com/U-eWKpORZ5A644gK/…
    • @MarkBoulder 它不调用任何名为name 的方法。你确定你没有改变什么?
    • 另外,为什么对 x.is_a 有任何疑问?散列还是 y.is_a?数组?
    • 你把g['name']改成g.name了吗?
    • 没有改变任何东西,只是直接粘贴到main_controller.rb。请查看该实时应用。
    猜你喜欢
    • 1970-01-01
    • 2017-11-07
    • 1970-01-01
    • 2016-10-17
    • 2012-07-13
    • 1970-01-01
    • 2016-05-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多