medeek
January 8, 2019, 3:04am
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
January 8, 2019, 3:59am
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
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
2 Likes
Fredo6
January 8, 2019, 7:54am
4
…or…
unique_array = original_array.uniq
count_array = unique_array.collect { |a| original_array.count(a) }
2 Likes
medeek
January 8, 2019, 11:06am
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.
Fredo6
January 8, 2019, 11:33am
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
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
2 Likes
medeek
January 8, 2019, 12:34pm
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.
Fredo6
January 8, 2019, 12:37pm
9
I guess you mean
array.group_by { |v| v }.map { |k, v| [k, v.size] }.sort_by { |k, v| k }.transpose
1 Like
medeek
January 8, 2019, 12:41pm
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.
It depends on whether it should be sorted by name or frequency. I interpreted it as frequency but I could be wrong.
1 Like
Fredo6
January 8, 2019, 2:56pm
12
Indeed… I thought Medeek wanted it sorted by data.
1 Like