Help with .unshift

ruby

#1

So this is unrelated to any specific lesson but I am trying to create a test for palindrome and this doesn't seem to work. I want unshift to add the letters one-by-one to the reverse_string array from the front so when i puts reverse_string, it will print backwards. But the output just prints a, a, a, a, a. I don't know why!

Also, ideally I want to unshift them to a string without having to .join the array elements. I learned through these lessons that strings and arrays are structured similarly so I thought it might work. I thought I could just .unshift each letter to reverse_string = "" but that doesn't look like it's recognized.

Any help would be appreciated!

Here's the code:

def palindrome?(string)
i = 0
reverse_string = []
while i < string.length
reverse_string.unshift(string[i])
puts reverse_string[i]
i += 1
end
if string == reverse_string
puts "We have a palindrome!"
return true
else
puts "This is not a palindrome."
end
end

palindrome?("abcba")


#2

Well, I figured it out on my own after staring at it and thinking intently on what was going on.

So I was increasing i by 1 every loop and still puts'ing reverse_string[i] after I made an addition to the array from the front. So after every i increase, I would print the next i in the array, which would happen to be the same letter once it got moved over to the right by the unshift. Ugh.

Here is my fixed code:

def palindrome?(string)
i = 0
reverse_array = []
while i < string.length
reverse_array.unshift(string[i])
i += 1
end
print reverse_array
reverse_string = reverse_array.join("")
if string == reverse_string
puts "We have a palindrome!"
return true
else
puts "This is not a palindrome."
end
end

palindrome?("abcba")


#3

Since you've solved your problem, the only way to add value to this thread is to segue it into a gallery. That means loads of other posts will pour into this thread, all with their own version to offer. Usually we remove 'asked and answered' topics, but this one will get a pass. Hope you won't mind, and that you become a regular contributor, @veryscarycary.

Here's something to kick us off...

re = /[\W\d]+/

str = "A man, a plan, a canal: Panama"

str.downcase!

str = str.gsub(re, "")

rts = str.reverse

print "Palindrome!" if str === rts

#4

I remember reading it, just not where, that strings are immutable and should not be treated as mutable. This means casting off an array, which is mutable and we can do with it what we like without losing the orginal string. An easy to agree with line of thinking, this.

Obviously, it's not demonstrated above. We've run roughshod over the input string and stripped it of non-word characters and lowered the case. This is important if we are to get an accurate reverse copy. The beauty is that it breaks the new string from the original. (Study up on how stingy Ruby is with memory and how it treats string objects.) We now have two unique objects.

 > rts.upcase!
=> "AMANAPLANACANALPANAMA"
 > str
=> "amanaplanacanalpanama"

#5

Oh I see. Thanks.

I don't understand what is going on with your 're' variable. It looks like you're subbing the 're' with nothing in 'str'. But it doesn't look like re is even in 'str'.


#6

re is a symbol for regular expression. When masked with a string object, only those characters that are not filtered out end up in the output string. Notice that in the example all non-alphanumeric characters have been stripped. There are no spaces, commas, or other punctuation. This is necessary if the flipped version of the string is to match.