2014-02-14 5 views
0

Для массива, как это:Получите массив значений ключа из массива хэшей?

a = [{a:'a',b:'3'},{a:'b',b:'2'},{a:'c',b:'1'}] 

Я хотел бы вернуть массив, содержащий значения для :a ключей, так:

['a', 'b', 'c'] 

Это может быть сделано с помощью:

a.map{|x|x[:a]} 

Интересно, есть ли собственный метод в Rails или Ruby, чтобы сделать это так?

a.something :a 
+3

Я бы сказал, что функция карты примерно такая же сжатая, как вы ее получите. –

+0

да, но не как читаемый ... = (я нашел эту работу с массивом моделей рельсов ... results.collect (&: key_name), но не с хэшами. –

+3

FYI #collect и #map - это то же самое. что второй не работает, так это то, что синтаксис, который вы использовали, отправляет с ключом как аргумент, а не вызывает [], как вы думаете. Я предпочитаю карту. Использование перечислимых карт очень читаемо и является одной из функций, которые я использую больше всего как программист Ruby. –

ответ

5

Вы можете сделать это самостоятельно:

class Array 
    def get_values(key) 
    self.map{|x| x[key]} 
    end 
end 

Тогда вы можете сделать это:

a.get_values :a 
#=> ["a", "b", "c"] 
+4

' get_keys' является неправильным. Вы возвращаете значения, а не ключи. –

+0

Вы правы, конечно. Не знаю, о чем я думал. –

+0

Я, вероятно, не сделал бы этого, хотя я думаю, что это менее читаемо, чем просто использование карты. Открытие Array является злым, и все, что вы называете этой функцией, не будет описывать, что он делает лучше, чем смотреть t map. Но я полагаю, что ОП попросил метод сделать это! –

1

Больше, чем вам нужно в этом случае, но с How to merge array of hashes to get hash of arrays of values вы можете получить их все один раз:

merged = a.inject{ |h1,h2| h1.merge(h2){ |_,v1,v2| [*v1,*v2] } } 
p merged[:a] #=> ["a", "b", "c"] 
p merged[:b] #=> ["3", "2", "1"] 

Кроме того, если вы используете что-то вроде Struct или OpenStruct для своих значений вместо хешей - или любого объекта, который позволяет вам получать значения «a» как метод, который не требует параметров, вы можете использовать удобство Symbol#to_proc для вашей карты:

AB = Struct.new(:a,:b) 
all = [ AB.new('a','3'), AB.new('b','2'), AB.new('c','1') ] 
#=> [#<AB a="a", b="3">, #<AB a="b", b="2">, #<AB a="c", b="1">] 

all.map(&:a) #=> ["a", "b", "c"] 
all.map(&:b) #=> ["3", "2", "1"] 
Смежные вопросы