Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

265
Visualizações
Sum array values to hash

I have an array like

[
    [358, 202102, 5],
    [358, 202112, 5],
    [358, 202102, 10],
    [311, 202103, 5],
    [311, 202101, 1],
    [311, 202101, 1],
    [311, 202115, 8],
    [311, 202101, 1],
    [311, 202101, 1]
]

I need a hash like this:

{
    358 => { 
        202102 => 15,
        202112 => 5
    },
    311 => {
        202103 => 5,
        202101 => 4,
        202115 => 8
    }
}

The order does not matter. Only the third values from each row of the array must be added up.

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

You can solve this using Enumberable#each_with_object as follows

a = [
    [358, 202102, 5],
    [358, 202112, 5],
    [358, 202102, 10],
    [311, 202103, 5],
    [311, 202101, 1],
    [311, 202101, 1],
    [311, 202115, 8],
    [311, 202101, 1],
    [311, 202101, 1]
]

a.each_with_object(Hash.new {|h,k| h[k] = Hash.new(0)}) do |(k1,k2,val), obj| 
  obj[k1][k2] += val 
end 
# => {358=>{202102=>15, 202112=>5}, 311=>{202103=>5, 202101=>4, 202115=>8}}

What this does is iterates over the Array (a) with an accumulator Object (obj).

This object is a Hash with a default proc where every time a new key is added its value is assigned as a new Hash with a default value of 0.

In the block arguments we deconstruct the Array into 3 arguments (k1,k2,val) so on first pass it would look something like this:

k1 = 358
k2 = 202102
val = 5 
obj[k1] 
#=> {358=> {}} 
obj[k1][k2] 
#=> {358 => {202102 => 0 }}
obj[k1][k2] += val
obj
#=> {358 => {202102 => 5 }}
over 4 years ago · Santiago Trujillo Relatório

0

Another way is to use the methods Hash#update (aka merge!) and Hash#merge that employ blocks to determine the values of keys that are present in both hashes being merged. See the docs for definitions of the three block variables. I've used an underscore for the first block variables (the common key of the hashes being merged) to signify that it is not used in the block calculation.

a = [
    [358, 202102, 5],
    [358, 202112, 5],
    [358, 202102, 10],
    [311, 202103, 5],
    [311, 202101, 1],
    [311, 202101, 1],
    [311, 202115, 8],
    [311, 202101, 1],
    [311, 202101, 1]
]
a.each_with_object({}) do |(x,y,n),h|
  h.update(x=>{y=>n}) do |_,old1,new1|
    old1.merge(new1) { |_,old2,new2| old2+new2 }
  end
end
  #=> {358=>{202102=>15, 202112=>5}, 311=>{202103=>5, 202101=>4, 202115=>8}}
over 4 years ago · Santiago Trujillo Relatório

0

At first I create a hash of hashes with the default value 0. After that I just add the values of the hash of hashes up based on the last value in the array.

aoa =
[
    [358, 202102, 5],
    [358, 202112, 5],
    [358, 202102, 10],
    [311, 202103, 5],
    [311, 202101, 1],
    [311, 202101, 1],
    [311, 202115, 8],
    [311, 202101, 1],
    [311, 202101, 1]
]


hash = Hash.new { |h,k| h[k] = Hash.new(0) }
aoa.each { |ary|  hash[ary[0]][ary[1]] += ary[2]}

pp hash

output:

{358=>{202102=>15, 202112=>5}, 311=>{202103=>5, 202101=>4, 202115=>8}}
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda