Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

196
Views
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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!