Sorting a list of values


#1

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]


Medeek Wall Plugin
#2

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
  else
    a << i
    b << 1 
  end
  counter += 1
  prev = i
end

#3

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

#4

…or…

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

#5

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.


#6

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

#7

This would handle the sorting too.

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

#8

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.


#9

I guess you mean

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

#10

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.


#11

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


#12

Indeed… I thought Medeek wanted it sorted by data.