Hendrik Kleine
Hendrik Kleine

Reputation: 105

Ruby - Loop IF x times and change condition

I would like to loop 20 times over an if statement, but each time it's run, some things must change.

Example:

    input = [0,0,0,44,754,22,0,632,2,22,0,2,nil,2,24,nil,666,90909,2,4,6,7,2,7,3,2,2,7,1,8,6,3,2,19,5,46]

Statement = "Statement THIS"

if
input[1] != nil &&
    input[2] == 0
  Statement.sub! "THIS", "WHERE #{input[8]} #{input[9]} THIS"
else
end

puts Statement #Statement WHERE 2 22 THIS

if
input[5] != nil &&
    input[6] == 0
  Statement.sub! "THIS", "AND #{input[12]} #{input[13]} THIS"
else
end

puts Statement #Statement WHERE 2 22 AND  2 THIS

if
input[9] != nil &&
    input[10] == 0
  Statement.sub! "THIS", "AND #{input[16]} #{input[17]} THIS"
else
end

puts Statement #Statement WHERE 2 22 AND  2 AND 666 90909 THIS

In the second IF statement the following things have changed:

  1. Each key has increased by 4 (1,2,8,9 became 5,6,12,13)
  2. The word WHERE has changed to AND

I would like this behaviour to repeat another 18 times, so the third IF statement has:

  1. Each key has increased by 4 (5,6,12,13 became 9,10,16,17)
  2. The word HELLO has changed to GOODBYE (however this rule is now redundant, since the second IF statement took care of it).

Upvotes: 1

Views: 910

Answers (3)

Cary Swoveland
Cary Swoveland

Reputation: 110665

n = 20

"STATEMENT WHERE %s THEN" % (1..1+4*(n-1)).step(4).with_object([]) { |i,a|
  a << "#{ input[i+7] } #{ input[i+8] }" unless input[i].nil? || input[i+1] != 0 }.
  join(" AND ") 
  #=> "Statement WHERE 2 22 AND  2 AND 666 90909 THEN" 

Upvotes: 0

BrunoF
BrunoF

Reputation: 3523

To loop 20 times you can use the times method.

arr_index = 1

20.times do
  if arr_index < 1
    operator = "WHERE"
  else
    operator = "AND"
  end


  if input[arr_index] != nil && input[arr_index + 1] == 0
    Statement.sub! "THIS", "#{operator} #{input[arr_index + 7]} #{input[arr_index + 8]} THIS"
  end

  arr_index += 4
end

Another option would be to change the contents of your input array or create another data structure (e.g., hash, array, array of hashes, hash of arrays) with the exact values you need for the loop. Thus, eliminating the need to increment the index by 4 at each iteration.

Also, unless Stamement is a class or a constant, convention dictates its name should be lower case (e.g., statement).

Good luck!

Upvotes: 1

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

input = [
  0,0,0,44,754,22,0,632,2,22,0,2,
  nil,2,24,nil,666,90909,2,4,6,7,
  2,7,3,2,2,7,1,8,6,3,2,19,5,46
]

(1..Float::INFINITY).step(4) do |i|
  i = i.to_i # is float here
  break Statement if i >= input.size
  next if input[i].nil? || !input[i+1].zero?

  keyword = Statement =~ /WHERE/ ? 'AND' : 'WHERE'
  Statement.sub! "THIS", "#{keyword} #{input[i+7]} #{input[i+8]} THIS"
end
#⇒ "Statement WHERE 2 22 AND  2 AND 666 90909 THIS"

Upvotes: 2

Related Questions