Question: I have a hash as follows:

```
{
  :student_name => ['A', 'B', 'C'],
  :total_marks => [100, 25, 50]
}

```

I want to sort each value (array) of this hash by the order of the corresponding element in the value for `:total_marks` when this array is sorted. The resultant hash should look like this:

```
{
  :student_name => ['B', 'C', 'A'],
  :total_marks => [25, 50, 100]
}

```

What is a scalable solution? This hash can have many other attributes.

Answer: 
Given the design of your hash, we need to first pair student and marks together.

```
h = {
    :student_name => ['A', 'B', 'C'],
    :total_marks => [100, 25, 50]
}

student_array = h[:student_name]
marks_array = h[:total_marks]

student_marks = []
student_array.each_with_index {|student, idx| student_marks << [student, marks_array[idx]]}
p student_marks  # Prints [["A", 100], ["B", 25], ["C", 50]]

```

So, now that we have a array where student and marks are paired, we will sort the above array using second element of sub-array

```
sorted = student_marks.sort {|i, j| i[1] <=> j[1]}
p sorted # Prints [["B", 25], ["C", 50], ["A", 100]]

```

Now that we have sorted student and marks, we will use it to update the original hash with sorted values

```
h[:student_name] = sorted.collect {|i| i[0]}
h[:total_marks]= sorted.collect {|i| i[1]}
p h

```

Finally, we have the result

```
{:student_name=>["B", "C", "A"], :total_marks=>[25, 50, 100]}

```

PS: Look at [sawa's answer](https://stackoverflow.com/questions/32166359/ruby-sorting-array-of-each-attribute-of-a-hashmap-wrt-one-attribute-of-the-has/32166420#32166420) for compact & elegant way of solving this.
```
marks, names = [h[:total_marks], h[:student_name]].transpose.
  sort_by(&:first).transpose
  #=> [[25, 50, 100], ["B", "C", "A"]] 
{ student_name: names, total_marks: marks }
  #=> {:student_name=>["B", "C", "A"], :total_marks=>[25, 50, 100]} 

```

The steps:

```
a = [h[:total_marks], h[:student_name]]
  #=> [[100, 25, 50], ["A", "B", "C"]] 
b = a.transpose
  #=> [[100, "A"], [25, "B"], [50, "C"]] 
c = b.sort_by(&:first)
  #=> [[25, "B"], [50, "C"], [100, "A"]] 
d = c.transpose
  #=> [[25, 50, 100], ["B", "C", "A"]] 
marks, names = d
  #=> [[25, 50, 100], ["B", "C", "A"]] 
marks
  #=> [25, 50, 100] 
names
  #=> ["B", "C", "A"] 
{ student_name: names, total_marks: marks }
  #=> {:student_name=>["B", "C", "A"], :total_marks=>[25, 50, 100]} 

```

Note that the two arrays transposed are 2xN and Nx2, where N is the number of students. Those arrays will require little memory and transposing them will be very fast compared to the sorting operation, except possibly for one-room schoolhouses.

I initially used `sort` rather than `sort_by(&:first)`, but changed to the latter after reading @theTinMan's comment on @Adam's answer, and then running this simple benchmark:

```
require 'fruity'

n = 100_000
m = (0..10_000).to_a
a = Array.new(n) { [m.sample, m.sample] }    

compare do
  sort    { a.sort }
  sort_by { a.sort_by(&:first) }
end

Running each test once. Test will take about 11 seconds.
sort_by is faster than sort by 5x ± 1.0 (results differ: [[0, 9243], [0, 3145],...

```

As indicated, `sort` and `sort_by(&:first)` do not have the same return values. When comparing pairs of tuples using `sort`, the second elements of the tuples are tie-breakers when the first elements are equal, whereas `sort_by(&:first)` has no tie-breaker.