How to simplify the process of classifying a value-based hash

Asked

Viewed 51 times

1

Oops, I’m new to the site, and I’m new to Ruby.

My question is: Is there a more efficient way to classify a hash according to the values?

I did the code below, but I’m sure it’s not the most efficient way.

agents = {"pedro" => 7, "lucas" => 12, "gabriel" => 15, "tadeu" => 4, "denis" => 22, "fabio" => 0}

agents_array = agents.sort_by { |k, v| v }.reverse

agents_array.map { |element| element.rotate! 1 }

agents_ordered = Hash.new

agents_array.each do |element|
    agents_ordered[element[1]] = agents[element[1]]
end

puts agents_ordered.inspect

Input: Agents = {"pedro" => 7, "Lucas" => 12, "Gabriel" => 15, "Tadeu" => 4, "Denis" => 22, "Fabio" => 0}

Expected outup: agents_ordered = {"Denis"=>22, "Gabriel"=>15, "Lucas"=>12, "pedro"=>7, "Tadeu"=>4, "Fabio"=>0}

What would be the most efficient way to classify?

2 answers

1

This problem can be solved by simply using only the libraries available in ruby.

agents = {"pedro" => 7, "lucas" => 12, "gabriel" => 15, "tadeu" => 4, "denis" => 22, "fabio" => 0}.sort_by{|key, value| value }.reverse.to_h
=> {"denis"=>22, "gabriel"=>15, "lucas"=>12, "pedro"=>7, "tadeu"=>4, "fabio"=>0}

Note that you only feel performance problems when the volume of data is zaroavelmente high. Follow a simple comparison of performance:

require 'benchmark'
require 'securerandom'

data = {}

1000000.times do |d|
  data[SecureRandom.hex] = rand(1..1000000)
end

Benchmark.bm do |x|
  #implementação mais rápida
  x.report do
    data.sort_by {|_key, value| value}.reverse.to_h
  end

  # um outra alternativa
  x.report do
    data.sort {|l, r| r.first <=> l.first }.to_h
  end

  # sua implementação
  x.report do
    agents_array = data.sort_by { |k, v| v }.reverse

    agents_array.map { |element| element.rotate! 1 }

    agents_ordered = Hash.new

    agents_array.each do |element|
      agents_ordered[element[1]] = data[element[1]]
    end
  end
end

   user     system      total        real
3.510000   0.010000   3.520000 (  3.539540)
7.150000   0.010000   7.160000 (  7.167365)
4.450000   0.010000   4.460000 (  4.457346)

1

You can simplify your code using only native methods:

agents = {"pedro" => 7, "lucas" => 12, "gabriel" => 15, "tadeu" => 4, "denis" => 22, "fabio" => 0}
# => {"pedro"=>7, "lucas"=>12, "gabriel"=>15, "tadeu"=>4, "denis"=>22, "fabio"=>0}

agents_ordered = agents.sort_by(&:last).reverse.to_h
# => {"denis"=>22, "gabriel"=>15, "lucas"=>12, "pedro"=>7, "tadeu"=>4, "fabio"=>0}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.