57705

Sorting an Array of hashes based on an Array of sorted values

Question:

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. :)

Answer1:

Using <a href="http://ruby-doc.org/core/Enumerable.html#method-i-sort_by" rel="nofollow">Enumerable#sort_by</a> or <a href="http://ruby-doc.org/core/Array.html#method-i-sort_by-21" rel="nofollow">Array#sort_by!</a>, 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.

Recommend

  • Isolate reactivity in an ordered list
  • SPSS creating a loop for a multiple regression over several variables
  • Entity Framework - Include in sub query? - Part 2
  • ruby - lazily iterate through an array
  • Entity Framework 4.1. Updating many-to-many relationships. Is this the right way?
  • Get all stl vector elements greater than a value
  • jquery if else condition for css api
  • Multiple statements if condition is true in shorthand if
  • What to use (best/good practice) for the secret key in HMAC solution?
  • How to search for a record and then delete it
  • How to wait till webViewDidFinishLoad gets completed
  • How can I train an intent in Watson conversation to accept any number?
  • bcrypt-nodejs compare method returns false every time
  • JOOQ nested condition
  • Sum values in array of hash if they have the same value
  • Python find continuous interesctions of intervals
  • smarty nested if condition is not working properly?
  • Emacs lua-mode issue: (void-function interactively-called-p)
  • distinct values from multiple fields within one table ORACLE SQL
  • How to turn (A, B, C) into (AB, AC, BC) with Pig?
  • .NET video play library which allows to change the playback rate?
  • std::remove_copy_if_ valgrind bytes in block are possibly lost in loss record
  • presentShareDialogWithParams posts to FB wall, but callback handler results say error
  • Sort List of Strings By Version
  • How to write order and limit within cakephp joins array
  • How to suppress a dialog
  • Rails Find when some params will be blank
  • Breeze - Deleted Items nav properties bug
  • ilmerge with a PFX file
  • Why value captured by reference in lambda is broken? [duplicate]
  • javaw.exe and eclipse startup problems
  • MySQL WHERE-condition in procedure ignored
  • Convert array of 8 bytes to signed long in C++
  • Rails 2: use form_for to build a form covering multiple objects of the same class
  • Understanding cpu registers
  • Why joiner is not used after Sequence generator or Update statergy
  • need help with bizarre java.net.HttpURLConnection behavior
  • Recursive/Hierarchical Query Using Postgres
  • Running Map reduces the dimensions of the matrices
  • UserPrincipal.Current returns apppool on IIS