как работать с массивом хешей - PullRequest
2 голосов
/ 27 января 2012
[[{"Postponed"=>10}], [{"Low"=>3}], [{"Medium"=>4}], [{"High"=>5}]]

это массив

как я могу получить значение, соответствующее определенному значению.

скажем, High возвращает 5 в этом. или как преобразовать этот массив хэшей в массив, чтобы поиск стал проще.

Я пытался:

find_all { |v| v['name'] == "Low" } 

но там написано:

cant convert String to Integer  

пожалуйста, предоставьте некоторые указания

Ответы [ 5 ]

9 голосов
/ 27 января 2012

Как насчет создания одного хеша для эффективного запроса?

arr.flatten.reduce(:merge)

#=> {"Postponed"=>10, "Low"=>3, "Medium"=>4, "High"=>5}
1 голос
/ 27 января 2012

Если у вас есть такой код, как:

array = [[{"Postponed"=>10}], [{"Low"=>3}], [{"Medium"=>4}], [{"High"=>5}]]

Затем превратите его в хэш рубина:

hash = array.inject({}) {|h, e| h.merge(e.first) }
# => {"Postponed"=>10, "Low"=>3, "Medium"=>4, "High"=>5}

Так что вы можете легко найти значение 'Low':

hash['Low']
# => 3

РЕДАКТИРОВАТЬ: Ответ Марка Томаса довольно велик, и короче, чем инъекция, поскольку он делает то же самое.Он написал это, прежде чем я ответил.Ницца;)

1 голос
/ 27 января 2012

В общем случае хэши не будут уникальными, поэтому вам нужно фильтровать, а не выбирать один с помощью индексации.Например, предположим, у вас есть это:

 arr = [[{:apple => 'abc'}], [{:banana => 'def'}], [{:coconut => 'ghi'}]]
 # => [[{:apple=>"abc"}], [{:banana=>"def"}], [{:coconut=>"ghi"}]]

Теперь давайте предположим, что вы хотите получить значение, соответствующее любому хешу, с ключом :coconut.Тогда просто используйте:

 arr.flatten.map { |h| h[:coconut] }.compact
 # => ["ghi"] 

Это дает вам список ответов.В этом случае есть только один соответствующий ключ, поэтому в массиве есть только одна запись.Если бы были другие хэши с ключом: coconut, то у вас было бы что-то вроде:

 # => ["ghi", "jkl", "mno"]

В целом, это очень необычная структура данных.Если вы контролируете структуру, то вам следует рассмотреть возможность использования объектов, которые могут возвращать вам разумные ответы желаемым образом, а не хешами.

0 голосов
/ 27 января 2012

Вы можете просто вызвать #flatten в исходном массиве. Это даст вам множество хешей. Я думаю, что вы действительно хотите, это всего лишь один хеш.

1.8.7 :006 > [[{"Postponed"=>10}], [{"Low"=>3}], [{"Medium"=>4}], [{"High"=>5}]].flatten
=> [{"Postponed"=>10}, {"Low"=>3}, {"Medium"=>4}, {"High"=>5}] 

Я бы спросил, что вы делаете, чтобы получить эту оригинальную структуру? Можно ли это изменить?

0 голосов
/ 27 января 2012

Как насчет этого?

  arr = [
    [{"Postponed"=>10}],
    [{"Low"=>3}], 
    [{"Medium"=>4}], 
    [{"High"=>5}]
  ]
  arr1 = []

  arr.each{|a|
    arr1.push(a[0])
  }

Хотя мне интересно, действительно ли вы просто хотите получить один хеш, который вы бы сделали так:

  myHash = {}

  arr.each{|a|
    a[0].each{|b, c|
      myHash[b] = c
    }
  }

Затем вы получите доступэто как myHash["Postponed"]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...