Как преобразовать массив хэшей в отсортированный хеш? - PullRequest
0 голосов
/ 22 января 2012

Если у меня есть массив хэшей, каждый с ключом дня:

[
    {:day=>4,:name=>'Jay'},
    {:day=>1,:name=>'Ben'},
    {:day=>4,:name=>'Jill'}
]

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

{
    :1=>[{:day=>1,:name=>'Ben'}],
    :4=>[{:day=>4,:name=>'Jay'},{:day=>4,:name=>'Jill'}]
}

Я использую Ruby 1.9.2 и Rails 3.1.1

Ответы [ 4 ]

4 голосов
/ 22 января 2012

Лично я бы не стал "сортировать" ключи (что соответствует порядку ввода по времени в Ruby 1.9), пока мне это не понадобилось.Тогда вы можете использовать group_by:

arr = [{:day=>4,:name=>'Jay'}, {:day=>1,:name=>'Ben'}, {:day=>4,:name=>'Jill'}]
arr.group_by { |a| a[:day] }
=> {4=>[{:day=>4, :name=>"Jay"}, {:day=>4, :name=>"Jill"}],
    1=>[{:day=>1, :name=>"Ben"}]}

Вместо этого сортируйте ключи, когда они вам действительно нужны.

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

Предполагается, что массив называется list, вот один из способов, использующий метод reduce:

list.reduce({}) { |hash, item|
  (hash[item[:day]] ||= []) << item; hash
}

Вот другой способ, использующий метод map, но вы должны иметь переменную-держатель:

hash = {}
list.each { |item|
  (hash[item[:day]] ||= []) << item
}

Получив несортированное хеш-слово в переменной foo, вы можете отсортировать его как

Hash[foo.sort]
0 голосов
/ 22 января 2012

В Rails вы можете использовать OrderedHash:

ActiveSupport::OrderedHash[arr.group_by { |a| a[:day] }.sort_by(&:first)]

Обновление: На самом деле в Ruby 1.9 хеш заказывается, поэтому использование ActiveSupport расширение не требуется:

Hash[arr.group_by { |a| a[:day] }.sort_by(&:first)]
0 голосов
/ 22 января 2012

Простой ответ:

data = [
    {:day=>4,:name=>'Jay'},
    {:day=>1,:name=>'Ben'},
    {:day=>4,:name=>'Jill'}
]

#expected solution
sol = {
    1=>[{:day=>1,:name=>'Ben'}],
    4=>[{:day=>4,:name=>'Jay'},{:day=>4,:name=>'Jill'}]
}

res = {}
data.each{|h|
  res[h[:day]] ||=  [] 
  res[h[:day]] << h
}

p res
p res == sol    #check value
p res.keys == sol.keys  #check order

Проблема с этим решением: хэш не сортируется в соответствии с запросом. (Та же проблема имеет решение Anurags ).

Так что вы должны немного изменить ответ:

res = {}
data.sort_by{|h| h[:day]}.each{|h|
  res[h[:day]] ||=  [] 
  res[h[:day]] << h
}

p res
p res == sol    #check value
p res.keys == sol.keys  #check order
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...