首页 > 解决方案 > 从嵌套哈希数组中优雅地返回匹配条件的值 - 在一行中

问题描述

我这几天一直在寻找解决这个问题的方法,希望有人能提供帮助。给定这个数据结构:

'foo' => {
  'bar' => [
    {
      'baz' => {'faz' => '1.2.3'},
      'name' => 'name1'
    },
    {
      'baz' => {'faz' => '4.5.6'},
      'name' => 'name2'
    },
    {
      'baz' => {'faz' => '7.8.9'},
      'name' => 'name3'
    }
  ]
}

我需要找到以“4.”开头的“faz”的值,而不使用每个。我必须使用“4”。value 作为哈希的键,我将在循环“bar”时创建(如果我还不知道“4.”的值,显然我不能这样做),而且我不想循环两次。

理想情况下,会有一个优雅的单行解决方案将值“4.5.6”返回给我。

我找到了这篇文章,但它没有解决这个数据结构的全部复杂性,并且给出的唯一答案太冗长了;循环两次解决方案更具可读性。我在 Rails 4 上使用 Ruby 2.3,但无法升级。有没有 Ruby 大师可以指导我?

标签: rubyruby-on-rails-4data-structures

解决方案


您可以使用select过滤结果。

data = {'foo' => {'bar' => [{'baz' => {'faz' => '1.2.3'}, 'name' => 'name1'}, {'baz' => {'faz' => '4.5.6'}, 'name' => 'name2'}, {'baz' => {'faz' => '7.8.9'}, 'name' => 'name3'}]}}

data.dig('foo', 'bar').select { |obj| obj.dig('baz', 'faz').slice(0) == '4' }
#=> [{"baz"=>{"faz"=>"4.5.6"}, "name"=>"name2"}]

# or if you prefer the square bracket style
data['foo']['bar'].select { |obj| obj['baz']['faz'][0] == '4' }

答案假定bar数组中的每个元素都有嵌套的属性baz -> faz

如果您只期望一个结果,您可以find改用。


推荐阅读