0

I have a hash and an array with same length like the following:

h = {:a => 1, :b => 2, :c => 3, :d => 4}
a = [2, 0, 1, 0]

I want to order the hash in increasing order of the values in the array. So the output would be something like:

h = {:b => 2, :d => 4, :c=> 3, :a => 1}

Ideally I want to introduce some randomness for ties. For the previous example, I want either the previous output or:

h = {:d => 4, :b => 2, :c=> 3, :a => 1}

This is what I tried.

b = a.zip(h).sort.map(&:last)
p Hash[b]
# => {:b=>2, :d=>4, :c=>3, :a=>1}

But I am not sure how to introduce the randomness.

3
  • 4
    I am not getting your array's role to sort the hash... Explain more about ..increasing order of the values in the array. Commented Apr 5, 2015 at 14:32
  • Each (key, value) corresponds to an value of the array. For example :a => 1 corresponds to 2 as :b => 2 corresponds to 0. In the output hash the "zeros" should come first, the "ones" second etc. Commented Apr 5, 2015 at 14:36
  • 2
    When addressing a question that seeks clarification (e.g., @Arup's), it is generally better to edit your question (e.g., "Edit: ...), than to respond with comments, as some readers may not read all he comments. Commented Apr 5, 2015 at 16:31

2 Answers 2

2
h.to_a.sort_by.each_with_index{|el,i| [a[i], rand]}.to_h
Sign up to request clarification or add additional context in comments.

3 Comments

I don't believe you need to_a.
@CarySwoveland You are right. I stumbled upon it. Since I'm not in the habit of sorting hashes, I was mildly surprised sort_by returned an array. Considered an explicit to_a better, to explain the to_h,but not sure about it. Not very important though.
A detail: Since Hash#each returns a two-element array, Enumerable#sort_by (and other Enumerable methods) acts on a hash the same way it acts on an array of two-element arrays.
1

You could modify what you have slightly:

def doit(h,a)
   Hash[a.zip(h).sort_by { |e,_| [e,rand] }.map(&:last)]
end

doit(h,a) #=> { b=>2, d=>4, c=>3, a=>1 }
doit(h,a) #=> { d=>4, b=>2, c=>3, a=>1 }
doit(h,a) #=> { b=>2, d=>4, c=>3, a=>1 }
doit(h,a) #=> { b=>2, d=>4, c=>3, a=>1 }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.