1

I have an array of hashes as given below:

user_quizzes = [{:id => 3897, :quiz_id => 1793, :user_id => 252}, {:id => 3897, :quiz_id => 1793, :user_id => 475}, {:id => 3897, :quiz_id => 1793, :user_id => 880}, {:id => 3897, :quiz_id => 1793, :user_id => 881}, {:id => 3897, :quiz_id => 1793, :user_id => 882}, {:id => 3897, :quiz_id => 1793, :user_id => 883}, {:id => 3897, :quiz_id => 1793, :user_id => 884}]

Also, based on a particular condition I took the values of 'user_id' key from the same hash and sorted it and the same array is given below:

sorted_user_ids = [880, 881, 882, 883, 884, 475, 252]

Now, I need the user_quizzes to be rearranged based on the order of user_id in sorted_user_ids array.

Can anyone please help me on this. :)

1 Answer 1

3

Using Enumerable#sort_by or Array#sort_by!, you can specify the key that will be used for comparison:

user_quizzes = [
  {:id => 3897, :quiz_id => 1793, :user_id => 252},
  {:id => 3897, :quiz_id => 1793, :user_id => 475},
  {:id => 3897, :quiz_id => 1793, :user_id => 880},
  {:id => 3897, :quiz_id => 1793, :user_id => 881},
  {:id => 3897, :quiz_id => 1793, :user_id => 882},
  {:id => 3897, :quiz_id => 1793, :user_id => 883},
  {:id => 3897, :quiz_id => 1793, :user_id => 884}
]
sorted_user_ids = [880, 881, 882, 883, 884, 475, 252]
user_quizzes.sort_by { |x| sorted_user_ids.index(x[:user_id]) }
# => [{:id=>3897, :quiz_id=>1793, :user_id=>880},
#     {:id=>3897, :quiz_id=>1793, :user_id=>881},
#     {:id=>3897, :quiz_id=>1793, :user_id=>882},
#     {:id=>3897, :quiz_id=>1793, :user_id=>883},
#     {:id=>3897, :quiz_id=>1793, :user_id=>884},
#     {:id=>3897, :quiz_id=>1793, :user_id=>475},
#     {:id=>3897, :quiz_id=>1793, :user_id=>252}]

Side note: sorted_user_ids.index(x[:user_id]) can become bottleneck (repeat O(n) operations), if the array is huge.

Build a hash that maps user_ids to orders in such case:

sorted_user_ids = [880, 881, 882, 883, 884, 475, 252]
order = Hash[sorted_user_ids.each_with_index.to_a]
# => {880=>0, 881=>1, 882=>2, 883=>3, 884=>4, 475=>5, 252=>6}
user_quizzes.sort_by { |x| order[x[:user_id]] }
# => same as above.
Sign up to request clarification or add additional context in comments.

2 Comments

In this particular case user_quizzes.sort { |a,b| a[:user_id] <=> b[:user_id] } is way more readable and easy to maintain. Though I understand the execution time penalties.
@mudasobwa, OP want to order by sorted_user_ids, not the user_id itself: ... rearranged based on the order of user_id in sorted_user_ids array.

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.