Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort Hash Keys based on order of same keys in array

Tags:

ruby

I need to sort an Hash according to order of keys present in other array:

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

Is there any way to do it in single line?

like image 897
Abhishek Avatar asked Mar 30 '16 07:03

Abhishek


4 Answers

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

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

The steps:

v = hash.values_at(*array)
  #=> [12, 23]
a = array.zip(v) 
  #=> [[:b, 12], [[:a, 23]]
a.to_h
  #=> {:b=>12, :a=>23}
like image 122
Cary Swoveland Avatar answered Nov 20 '22 15:11

Cary Swoveland


You can try something like this:

array = [:b, :a] 
{ a: 23, b: 12 }.sort_by { |k, _| array.index(k) }.to_h
#=> {:b=>12, :a=>23}
like image 22
Ilya Avatar answered Nov 20 '22 15:11

Ilya


If

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

As a one liner:

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

As for ordering, it was some time ago, when ruby changed the implementation where the hash keys are ordered according to insert order. (Before that there was no guarantee that keys would be sorted one way or another).

like image 3
Candide Avatar answered Nov 20 '22 17:11

Candide


I do not see any sorting, I think essentially you are doing this:

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}
like image 1
shivam Avatar answered Nov 20 '22 16:11

shivam