Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

394
Vistas
How to combine and print values of nested object structure?

I have an array of hashes and each hash needs to be printed out on the same line.

init_cards_j = [
  { init1: [{ num: 6, head: 1 }, { num: 10, head: 1 }] },
  { init2: [{ num: 53, head: 1 }, { num: 60, head: 1 }] },
  { init3: [{ num: 77, head: 5 }] },
  { init4: [{ num: 89, head: 1 }] }
]

I want it to be looked like this:

Card 6: 1 head / Card 10: 1 head
Card 53: 1 head / Card 60: 1 head
Card 77: 5 head
Card 89: 1 haed

I tried below:

init_cards_j.each_index do |index|
  init_cards_j[index].values[0].each do |pair|
    init_cards_j[index].each do |key, value|
      value.each do |pair|
        puts "Card #{pair[:num]}: #{pair[:head]} kettle head. / "
      end
    end
  end
end

Which outputs the data as:

Card 6: 1 kettle head. / 
Card 10: 1 kettle head. / 
Card 6: 1 kettle head. / 
Card 10: 1 kettle head. / 
Card 53: 1 kettle head. / 
Card 60: 1 kettle head. / 
Card 53: 1 kettle head. / 
Card 60: 1 kettle head. / 
Card 77: 5 kettle head. / 
Card 89: 1 kettle head. / 

I am sorry that my array is so nested as I need to sort the order by num for each hash, I put them in an array.

Thanks in advance!

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

You can iterate the hashes in init_cards_j via each and for each hash call each_value to traverse its values. Then, instead of printing every card right away, you can generate an intermediate array via map and join the result using your separator string:

init_cards_j.each do |hash|
  hash.each_value do |values|
    puts values.map { |c| "Card #{c[:num]}: #{c[:head]} head" }.join(' / ')
  end
end

But it would be easier to convert the array of hashes to a single hash: (assuming that their keys are unique)

cards = {
  init1: [{ num: 6, head: 1 }, { num: 10, head: 1 }],
  init2: [{ num: 53, head: 1 }, { num: 60, head: 1 }],
  init3: [{ num: 77, head: 5 }],
  init4: [{ num: 89, head: 1 }]
}

If you must retain the given structure, you could convert it on the fly:

cards = init_cards_j.inject(&:merge)

This makes the loop a bit simpler:

cards.each_value do |values|
  puts values.map { |c| "Card #{c[:num]}: #{c[:head]} head" }.join(' / ')
end

To further refine the output, you can separate the looping from the card description by extracting the latter into a method:

def description(card)
  "Card #{card[:num]}: #{card[:head]} head"
end

init_cards_j.each do |hash|
  hash.each_value do |values|
    puts values.map { |card| description(card) }.join(' / ')
  end
end

You can now adding more logic to the output string by editing the description method, e.g.:

def description(card)
  if card[:head] == 1
    "Card #{card[:num]}: #{card[:head]} head"
  else
    "Card #{card[:num]}: #{card[:head]} heads"
  end
end

The above can be written much more compact, but I'll leave the optimization to you.

over 4 years ago · Santiago Trujillo Denunciar

0

I would recommend @Stefan's first answer, but here is another way to achieve the same result.

We might begin with a helper method, which of course you can test separately:

def print_num_and_head(g)
  print "Card %d: %d head" % g.values_at(:num, :head)
end

If

g = {:num=>6, :head=>1})

then

print_num_and_head(g)

displays

Card 6: 1 head

without a line terminator.

We may then write:

init_cards_j.each do |h|
  _, (g, *arr) = h.flatten
  print_num_and_head(g)
  arr.each do |g|
    print ' / '
    print_num_and_head(g)
  end
  puts   
end

prints

Card 6: 1 head / Card 10: 1 head
Card 53: 1 head / Card 60: 1 head
Card 77: 5 head
Card 89: 1 head

Here I've used Ruby's powerful array#decomposition (a.k.a array disambiguation) syntax to advantage:

If

h = { init1: [{ num: 6, head: 1 }, { num: 10, head: 1 }] }

then

_, (g, *arr) = h.flatten
  #=> [:init1, [{:num=>6, :head=>1}, {:num=>10, :head=>1}]]
_ #=> :init1
g #=> {:num=>6, :head=>1}
arr
  #=> [{:num=>10, :head=>1}]

I've employed the common convention of representing a block variable with an underscore when it is not used in the block calculation.

See this article for a fuller explanation array decomposition.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda