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

190
Visualizações
Each loop skipping an element when deleting an element within the each loop

I was just messing about trying to get all the 2, 3 and 4 combos in a size 4 array (e.g 1&2,1&3,1&4,2&3 and so on) and I came across this weird issue that I cannot figure out. Why is primary_num returning 4 on the 3rd loop but the index 0 value is 3, shouldn't it return 3.

The code is partial code but obviously can't complete it until I figure this part out. My next plan was to try a recursive function but was curious why this is happening when it works fine on loop 1 & 2. I know there is a permutations method but I am just experimenting.

lucky15 = [1,2,3,4]

doubles = []
triples = []
fourfold = []

lucky15.each_with_index do |primary_num, index|
    
    lucky15.delete(index)
    p lucky15[0]
    p primary_num
    p lucky15
end

The output for the puts was:

1 #p lucky15[0]
1 #p primary_num
[1, 2, 3, 4]

2 #p lucky15[0]
2 #p primary_num
[2, 3, 4]

3 #p lucky15[0]
4 #p primary_num <--- why 4 not 3????
[3, 4]

To explain what I was trying to do as my first revision:

lucky15 = [1,2,3,4]

doubles = []
triples = []
fourfold = []

lucky15.each_with_index do |primary_num, index|
  lucky15.delete(index)

  each.lucky15 do |num|
    doubles << "#{primary_num} && #{num}"
  end
end

puts doubles
over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

trying to get all the 2, 3 and 4 combos

To calculate combinations manually, you typically use nested loops. For "doubles", you could use:

lucky15 = [1, 2, 3, 4]
doubles = []

(0...lucky15.size-1).each do |i|
  (i+1...lucky15.size).each do |j|
    doubles << lucky15.values_at(i, j)
  end
end

doubles #=> [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]

The outer loop increments an index i from 0 to 2 (because 2 is the maximum starting-index for a "2 combo"). The inner loop then increments another index j from i's successor up to 3 (the array's end index). This way, the inner loop "skips" the indices that have already been visited by i: (so there's no need to delete anything)

1 2 3 4  # array values
0 1 2 3  # array indices
i j      # lucky15.values_at(0, 1)

1 2 3 4
0 1 2 3
i   j    # lucky15.values_at(0, 2)

1 2 3 4
0 1 2 3
i     j  # lucky15.values_at(0, 3)

1 2 3 4
0 1 2 3
  i j    # lucky15.values_at(1, 2)

1 2 3 4
0 1 2 3
  i   j  # lucky15.values_at(1, 3)

1 2 3 4
0 1 2 3
    i j  # lucky15.values_at(2, 3)

To get "triples", you need another level:

triples = []

(0...lucky15.size-2).each do |i|
  (i+1...lucky15.size-1).each do |j|
    (j+1...lucky15.size).each do |k|
      triples << lucky15.values_at(i, j, k)
    end
  end
end

triples #=> [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]

Visualized:

1 2 3 4
0 1 2 3
i j k

1 2 3 4
0 1 2 3
i j   k

1 2 3 4
0 1 2 3
i   j k

1 2 3 4
0 1 2 3
  i j k

However, Ruby already has the above methods built-in as combination so there's no need to re-invent the wheel:

doubles = lucky15.combination(2).to_a
#=> [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]

triples = lucky15.combination(3).to_a
#=> [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]
over 4 years ago · Santiago Trujillo Relatório

0

Looks like the delete method wasn't doing what you thought it was (same here, I had to run a modified version of this with more printing to see it):

lucky15 = [1,2,3,4]

doubles = []
triples = []
fourfold = []

lucky15.each_with_index do |primary_num, index|
    puts "Index: #{index}"   
    puts "0th element before delete: #{lucky15[0]}"
    lucky15.delete(index)
    puts "0th element after delete: #{lucky15[0]}"
    puts "primary_num: #{primary_num}"
    puts "lucky15: #{lucky15}"
end

Output:

Index: 0
0th element before delete: 1
0th element after delete: 1
primary_num: 1
lucky15: [1, 2, 3, 4]
Index: 1
0th element before delete: 1
0th element after delete: 2
primary_num: 2
lucky15: [2, 3, 4]
Index: 2
0th element before delete: 2
0th element after delete: 3
primary_num: 4
lucky15: [3, 4]

The index variable is holding the index each time, but delete is searching for the element in the array and deleting it if it's present. So when you use delete that way, you're deleting an element equal to the index from the array during each iteration, if such an element exists in the array during that iteration.

You probably want delete_at (https://ruby-doc.org/core-3.0.0/Array.html#method-i-delete_at).

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