2016-03-30 2 views
1

мне нужно сортировать Hash в соответствии с порядком ключей, находящихся в другой массив:сортировки ключей хеша на основе порядка одинаковых ключей в массиве

hash = { a: 23, b: 12 } 
array = [:b, :a] 
required_hash #=> { b: 12, a: 23 } 

Есть ли способ сделать это в одной строке?

+1

Я не знаю, Руби, но концептуально хэш-карты не упорядочены. Но вы можете отсортировать значения, имеющие следующий выход '12, 23'. Попробуйте что-то вроде 'array.map {| k | хэш [к]} '. –

+1

Каковы значения 'a' и' b'? – sawa

+2

@engineer, поскольку Ruby v.1.9, появившийся несколько лет назад, сохраняется порядок вставки хеш-ключей. Идея хэш-ключей заказанного остается спорным, однако. Лично я использовал это свойство довольно много. –

ответ

6
hash = { a: 23, b: 12 } 
array = [:b, :a] 

array.zip(hash.values_at(*array)).to_h 
    #=> {:b=>12, :a=>23} 

Шаги:

v = hash.values_at(*array) 
    #=> [12, 23] 
a = array.zip(v) 
    #=> [[:b, 12], [[:a, 23]] 
a.to_h 
    #=> {:b=>12, :a=>23} 
+0

Мне лично нравится @ Илья ответ ниже –

1

Я не вижу никакой сортировки, я думаю, по существу, вы делаете это:

hash = { a:23, b:12 } 
array = [:b, :a] 
res = {} 
array.each { |key| res[key] = hash[key] } && res # `&& res` is just syntax sugar to return result in single line 
#=> {:b=>12, :a=>23} 
2

Если

hash = { a:23, b:12 } 
array = [:b, :a] 

Как один лайнер:

Hash[array.map{|e| [e, hash[e]]}] 

Что касается заказа, это было некоторое время назад, когда рубин изменил реализацию, в которой хеш-ключи упорядочены в соответствии с порядком вставки. (До этого не было никакой гарантии, что ключи будут сортироваться так или иначе).

+0

Хороший ответ, но я никогда не пойму, почему люди говорят (sic), «вот один лайнер», за которым следует одна строка кода. –

+0

@CarySwoveland Лично я делаю это, чтобы подчеркнуть, что Ruby является кратким, и вы можете написать много вещей в один лайнер (по сравнению с C#/Java). – Candide

+0

Новые строки не имеют смысла в C♯/Java, вы всегда можете написать любую программу C♯/Java в одной строке, независимо от сложности, это не уникальная особенность Ruby. –

4

Вы можете попробовать что-то вроде этого:

array = [:b, :a] 
{ a: 23, b: 12 }.sort_by { |k, _| array.index(k) }.to_h 
#=> {:b=>12, :a=>23} 
Смежные вопросы