Sorting a list of values

This question is more a generic programming type question rather than specifically related to the API but here goes anyway.

I have an array or list of values like so:

original_array = [6.125, 6.125, 8.625, 8.625, 29.0, 8.625, 29.0, 41, 2.25, 2.25, 62.0, 62.0, 62.0]

I would like to create two lists from this list. One list with each occurrence of the values listed:

[6.125, 8.625, 29, 41, 2.25, 62]

and another list that gives the number of times each value occurs in the original list:

[2, 3, 2, 1, 2, 3]

My first draft at this would be:

sorted_array = original_array.sort

a = []
b = []
counter = 0

for i in sorted_array
   if i == prev
     b[counter] = b[counter] + 1
    a << i
    b << 1 
  counter += 1
  prev = i

This is the simplest code I can come up with. Maybe the rather bland { |v| v } block can be omitted some way.

array.group_by { |v| v }.map { |k, v| [k, v.size] }.transpose


unique_array = original_array.uniq
count_array = unique_array.collect { |a| original_array.count(a) }

And if I want the data sorted (smallest to largest) how about:

unique_array = original_array.uniq.sort
count_array = unique_array.collect { |a| original_array.count(a) }

That seems about as compact as you can get.

Wow, I thought my little chunk of code was fairly simple and compact. One just needs to better leverage Ruby and all of its methods.

If you wish an double array with the tuple [unique value, nb_occurences], with sorting, that is,

[[2.25, 2], [6.125, 2], [8.625, 3], [29.0, 2], [41, 1], [62.0, 3]]

…then use

original_array.group_by { |v| v }.collect { |v, ls| [v, ls.length] }.sort

You can decompose each of the 3 operations in the Ruby Console to see what it gives

h = original_array.group_by { |v| v }
lst = h.collect { |v, ls| [v, ls.length] }
lst_final = lst.sort
1 Like

This would handle the sorting too.

array.group_by { |v| v }.map { |k, v| [k, v.size] }.sort_by { |k, v| v }.transpose

Alright, I’m going to give this a try. This little sorting and enumeration algorithm will help me organize and properly present my cripple stud data in my new estimator module of the Wall plugin.

Thank-you for sorting me out.

I guess you mean

array.group_by { |v| v }.map { |k, v| [k, v.size] }.sort_by { |k, v| k }.transpose
1 Like

I’m not sure yet which actual method I’ll use. The double array is convenient in the fact that I only have one array as the output and I can then loop through this single array to generate my final output.

It looks like either method will get me there. Now I just need to work on the javascript end, which is always a little fun.

It depends on whether it should be sorted by name or frequency. I interpreted it as frequency but I could be wrong.

1 Like

Indeed… I thought Medeek wanted it sorted by data.

1 Like