2014-10-01 4 views
0

ПОЛУЧИТЬ к API конечной точке я работаю с возвратами JSon с непоследовательным порядком контактов, либоключей Карты с тем же именем

{"contacts"=>[ 
    {"id"=>$UUID_0, "name"=>nil, "email"=>$EMAIL_0, "phone"=>$PHONE_0, "type"=>"foo"}, 
    {"id"=>$UUID_1, "name"=>nil, "email"=>$EMAIL_1, "phone"=>$PHONE_1, "type"=>"bar"} 
]} 

или

{"contacts"=>[ 
    {"id"=>$UUID_1, "name"=>nil, "email"=>$EMAIL_1, "phone"=>$PHONE_1, "type"=>"bar"}, 
    {"id"=>$UUID_0, "name"=>nil, "email"=>$EMAIL_0, "phone"=>$PHONE_0, "type"=>"foo"} 
]} 

The "type" значений являются только статические объекты в этих ответах, поэтому я хотел бы сопоставить это так, чтобы типы контактов были ключами, содержащими другие пары:

{ 
    "foo"=>{"id"=>$UUID_0, "name"=>$NAME_0, "email"=>$EMAIL_0, "phone"=>$PHONE_0}, 
    "bar"=>{"id"=>$UUID_1, "name"=>$NAME_1, "email"=>$EMAIL_1, "phone"=>$PHONE_1} 
} 

Решение для меня не очевидно.

+1

См [Enumerable # group_by] (http://ruby-doc.org/core-2.1.3/Enumerable.html#method-i-group_by) – Kyle

+0

Где '$ NAME_0',' $ NAME_1'? – falsetru

+0

'$ NAME' - это произвольно сгенерированная строка для имен контактов, а также остальные значения типа' 'не' '. –

ответ

0
Hash[data['contacts'].map { |c| [c['type'], c] }] 
+0

Это прекрасно. Спасибо, Кайл. –

1

Если вы используете Ruby on Rails или, по крайней мере, ActiveSupport, вы можете попробовать index_by вместо group_by: он не будет помещать значения в массивы.

hash['contacts'].index_by {|r| r['type']} 
=> 
{ 
    "bar" => { 
    "id" => "asdf", 
    "name" => nil, 
    "email" => "EMAIL_1", 
    "phone" => "PHONE_1", 
    "type" => "bar" 
    }, 
    "foo" => { 
    "id" => "asdf", 
    "name" => nil, 
    "email" => "EMAIL_0", 
    "phone" => "PHONE_0", 
    "type" => "foo" 
    } 
} 
+0

К сожалению, я не использую ни одного, хотя это кажется идеальным. Благодаря! –

0

Это может быть сделано с перечислимых # уменьшить:

hash['contacts'].reduce({}) {|m,c| m[c['type']] = c;m} 

Как это работает:

  1. пустой хэш является отправной точкой.
  2. Блок вызывается один раз для каждого элемента в списке контактов. Блок получает хэш, который мы строим как m, и текущий контакт как c.
  3. В блоке присвойте c хэшу на основе его type и верните хэш до сих пор.
  4. Конечный результат - это последнее возвращаемое значение блока.
+1

Предлагаю вам использовать [Enumerable # each_with_object] (http://www.ruby-doc.org/core-2.1.1/Enumerable.html#method-i-each_with_object), а не 'снижать', чтобы избавиться от это надоедливый '; m'. –

+0

Кроме того, вы можете сохранить 'уменьшение' и изменить блок на' {| g, h | g.update ({h ['type'] => h})} '(a.k.a.' merge! '). –

Смежные вопросы