I have a hash of ids and their scores, it's something like this:
@objects = {1=>57, 4=>12, 3=>9, 5=>3, 55=>47, 32=>39, 17=>27, 29=>97, 39=>58}
How can I pick the top five and drop the rest ?
I'm doing this:
@orderedObject = @objects.sort_by {|k,v| v}.reverse
=>[[29, 97], [39, 58], [1, 57], [55, 47], [32, 39], [17, 27], [4, 12], [3, 9], [5, 3]]
Then I do this: only Keys of the @orderedObjects
:
@keys = @orderedObject.map { |key, value| key }
which gives me:
=>[29, 39, 1, 55, 32, 17, 4, 3, 5]
ALL I need is [29, 39, 1, 55, 32]
the first 5 indexes. But I'm stuck I don't know how to do this.
You can do
@objects = {1=>57, 4=>12, 3=>9, 5=>3, 55=>47, 32=>39, 17=>27, 29=>97, 39=>58}
@objects.sort_by { |_, v| -v }[0..4].map(&:first)
# => [29, 39, 1, 55, 32]
@objects.sort_by { |_, v| -v }.first(5).map(&:first)
# => [29, 39, 1, 55, 32]
A variant of Prof. Arup's answer:
objects = {1=>57, 4=>12, 3=>9, 5=>3, 55=>47, 32=>39, 17=>27, 29=>97, 39=>58}
objects.sort_by { |k,v| -v }.first(5).to_h.keys #=> [29, 39, 1, 55, 32]
Now suppose 3=>9
were instead 3=>39
and you wanted the keys corresponding to the top 5 values (which, in this case, would be 6 keys, as 39
is the fifth largest value, 3=>39
and 32=>39
), you could first compute:
threshold = objects.values.sort.last(5).min #=> 39
If you wanted the keys to be ordered by the order of values threshold
or larger,
objects.select { |_,v| v >= threshold }.sort_by { |_,v| -v }.map(&:first)
#=> [29, 39, 1, 55, 3, 32]
If you don't care about the order,
objects.select { |_,v| v >= threshold }.keys #=> [1, 3, 55, 32, 29, 39]
我可以建议这个更详细的要求红宝石> 1.9
Hash[@objects.sort_by{|k,v| -v}.first(5)].keys
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.