1

I was trying to create a Table of Contents in the command line. Each element in the array is a string variable.

arr = [chap1, chap1_page, chap2, chap2_page, chap3, chap3_page]
x = 0

until x == arr.length
if ((arr[x] != 0 ))
    puts arr[x].ljust(line/2) + arr[x += 1].rjust(line/2)       
end 
x += 1
end

I was wondering if someone could explain the second half of the puts statement. I'm not sure why arr[x+=1] works but arr[x+1] does not. As far as I know, they are the same, are they not?

2
  • Side note: this isn't really idiomatic Ruby. Are you familiar with Array#each? As a side effect, you wouldn't need to use a counter variable like this. More on topic: what do you mean by "works" and "does not [work]"? If x is 2, then arr[x + 1] should return the element at index 3. What output are you seeing that you didn't expect? Commented Apr 14, 2016 at 4:21
  • I want the output to format where the chapter is on the left and page is on the right and then repeat on the next line. But with x+1 i am seeing the next line show chap1_page ....chap2. Commented Apr 14, 2016 at 11:56

2 Answers 2

1

When dealing with Enumerables like arrays and hashes, it's useful to search the documentation to see if there's something there that will make your code higher level and more expressive. In this case, you can use each_cons to give you the pairs so you don't need to use array indexes at all:

2.3.0 :004 > [1,2,3,4].each_cons(2).to_a
 => [[1, 2], [2, 3], [3, 4]]

Also, rather than using if statements, it's better IMO to use select and reject.

Also, intermediate local variables can make your code more readable.

Using these ideas, your code could look something like this:

array = [chap1, chap1_page, chap2, chap2_page, chap3, chap3_page]

width = line / 2

array.each_cons(2).reject { |x,y| x == 0 }.each do |left, right|
  puts left.ljust(width) + right.ljust(width)
end

(I haven't tested this code, but it shows the general idea.)

You could break down those enumerable calls and assign intermediate values to local variables if that makes it clearer for you:

array = [chap1, chap1_page, chap2, chap2_page, chap3, chap3_page]
width = line / 2

pairs = array.each_cons(2)
nonzero_pairs = pairs.reject { |x,y| x == 0 }
nonzero_pairs.each do |left, right|
  puts left.ljust(width) + right.rjust(width)
end
Sign up to request clarification or add additional context in comments.

Comments

0

x + 1 returns that value and has no side effect (does not change the reference of x). x += 1 reassigns x and returns that value.

1 Comment

Thank you, I knew that the += was reassigning x but could not understand why it was giving me the output I wanted. I realize now that I am incrementing x twice, once in the puts statement and a second time at the end of the loop. THAT is why my output is what I want it to be.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.