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: 
If you want the code to be simple and involve the least amount of indirection, I'd recommend holding the student's name and total mark together, rather than as parallel arrays. This way, you can add extra fields without then having to rewrite your sort routine (which would otherwise have to now resort *another* parallel array for the new field).

```
ExamResult = Stuct.new(:student_name, :total_mark)

exam_results = [
    ExamResult.new('Adam', '25'),
    ExamResult.new('Sajani', '100'),
    ExamResult.new('Sawa', '50')
]

# Sort
exam_results.sort_by &:total_mark

```

As for scalability, that will *heavily* depend on what *kind* of scalability you need. The above method will likely handle hundreds of thousands of `ExamResult`'s without much effort. If you want to do *millions* upon *millions* or exam results without overloading your memory then you're going to need a better way of sorting the grades and streaming exam results anyway, regardless of how you've structured it.
```
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.