2

I have two arrays:

a = [ 1, 0, 2, 1, 0]
b = ['a', 'b', 'c', 'd', 'e']

I want to order the b array according to a's elements values. I can make this by merging the two arrays into a Hash and the order by key:

h = Hash[b.zip a]
=> {"a"=>1, "b"=>0, "c"=>2, "d"=>1, "e"=>0}

h2 = Hash[h.sort_by{|k, v| v}]
=> {"b"=>0, "e"=>0, "a"=>1, "d"=>1, "c"=>2}

array = h2.keys
=> ["b", "e", "a", "d", "c"]

Where there is a tie the order may be chosen arbitrary.

Is there a way (maybe more compact), I can achieve this without using the hash.

2 Answers 2

3
a.zip(b).sort.map(&:last)

In parts:

p a.zip(b) # => [[1, "a"], [0, "b"], [2, "c"], [1, "d"], [0, "e"]] 
p a.zip(b).sort # => [[0, "b"], [0, "e"], [1, "a"], [1, "d"], [2, "c"]] 
p a.zip(b).sort.map(&:last) # => ["b", "e", "a", "d", "c"]
Sign up to request clarification or add additional context in comments.

3 Comments

...which can alternatively be written: [a,b].transpose.sort.map(&:last).
@CarySwoveland It's not an exact equivalent, as the error behavior is different. If the arrays are different sizes, zip will pad with nil but transpose will throw an error.
Thanks, @MarkThomas. Yes, but in this case I thought it was reasonable to assume the arrays are of the same size, both because they are in the example and because no rule was given for the case where they are unequal in size. But you do make a good good point about zip vs. transpose.
2
a = [ 1, 0, 2, 1, 0]
b = ['a', 'b', 'c', 'd', 'e']

p b.sort_by.each_with_index{|el,i| a[i]}
# => ["b", "e", "a", "d", "c"]

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.