How to Do String Comparison in Ruby

comparing two strings in ruby

From what you printed, it seems var2 is an array containing one string. Or actually, it appears to hold the result of running .inspect on an array containing one string. It would be helpful to show how you are initializing them.

irb(main):005:0* v1 = "test"
=> "test"
irb(main):006:0> v2 = ["test"]
=> ["test"]
irb(main):007:0> v3 = v2.inspect
=> "[\"test\"]"
irb(main):008:0> puts v1,v2,v3
test
test
["test"]

String || comparison operator in Ruby

'X' || 'O' just says X or O. And since any string is truthy it always returns X. So any spot where you’ve said [('X' || 'O')], you’ve really just said ['X'].

Because of this, you’re only ever checking if a whole line of 3 is all X.

I don’t really understand how you’re trying to test this, but I feel like you’d be better off running the function twice first handing in X and then handing in O if it didn’t find X as a winner, as opposed to trying to check both as once.

Alternatively you could instead have the function return 'X', 'O', or nil and then you could have it only run the function once. The string returned would be who won and if it’s nil then no one won. I would also recommend making a loop for this. I find it easier to read.

Here's how I would solve the problem.

ROWS = [
[1,2,3],
[4,5,6],
[7,8,9],

[1,4,7],
[2,5,8],
[3,6,9],

[1,5,9],
[7,5,3],
]

def find_winner(board)
ROWS.each do |row|
# subtract 1 because the ROWS is 1-indexed (like a phone dial) but arrays are 0-indexed
row_values = row.map { |v| board[v - 1] }
return('X') if row_values.all?('X')
return('O') if row_values.all?('O')
end

return(nil)
end

test1 = [
'X', 'X', 'X',
'O', 'X', 'O',
'O', 'O', '',
]
puts "Winner of test1: #{find_winner(test1).inspect}"
"X"

test2 = [
'X', '', 'X',
'X', 'O', 'O',
'X', 'O', 'X',
]
puts "Winner of test2: #{find_winner(test2).inspect}"
"X"

test3 = [
'O', 'X', 'X',
'O', 'X', 'O',
'O', 'O', '',
]
puts "Winner of test3: #{find_winner(test3).inspect}"
"O"

test4 = [
'O', 'X', 'O',
'X', 'O', 'X',
'O', 'O', 'X',
]
puts "Winner of test4: #{find_winner(test4).inspect}"
"O"

test5 = [
'O', 'X', 'O',
'O', 'X', 'O',
'X', 'O', 'X',
]
puts "Winner of test5: #{find_winner(test5).inspect}"
nil

How do I do String comparison in Ruby?

The string returned by gets will have a linebreak at the end. Use String#chomp to remove it (i.e. state_abbreviation = gets.chomp).

PS: Your code would look much cleaner (IMHO) if you used case-when instead of if-elsif-elsif.

Comparing two strings using (greater than sign) in Ruby?

String includes the Comparable module, which defines <, >, >=, etc, based on the base class's compare (<=>) method. So if string a comes alphabetically prior to string b, a <=> b returns -1, and < returns true. The same <=> method is used for sorting strings, so you can imagine that in a sorted array of strings, each string is 'less than' its neighbor to the right.

Ruby: String Comparison Issues

gets returns the entire string entered, including the newline, so when they type "M" and press enter the string you get back is "M\n". To get rid of the trailing newline, use String#chomp, i.e replace your first line with answer = gets.chomp.

Is == in Ruby always value equality?

In Ruby, == can be overloaded, so it could do anything the designer of the class you're comparing wants it to do. In that respect, it's very similar to Java's equals() method.

The convention is for == to do value comparison, and most classes follow that convention, String included. So you're right, using == for comparing strings will do the expected thing.

The convention is for equal? to do reference comparison, so your test a.object_id == b.object_id could also be written a.equal?(b). (The equal? method could be defined to do something nonstandard, but then again, so can object_id!)

(Side note: when you find yourself comparing strings in Ruby, you often should have been using symbols instead.)

String comparison in Ruby

As I understand, you have two strings, s1 and s2, from which you obtain two strings:

ss1 = s1[0,n]
ss2 = s2[0,n]

where

n = [s1.size, s2.size].min

and you want to know if the characters of ss2 can be rearranged to equal ss1. If my understanding is correct, that would be true if and only if the following is true:

ss1.chars.sort == ss2.chars.sort

Example:

s1 = "ebcda"
s2 = "adcbefr"
n = [s1.size, s2.size].min #=> 5
ss1 = s1[0,n] #=> "ebcda"
ss2 = s2[0,n] #=> "adcbe"
ss1.chars.sort == ss2.chars.sort #=> true

ruby string comparisons .match vs .eql?

As always, don't just use methods without reading their documentation. There can be important notes.

Here's eql?:

Two strings are equal if they have the same length and content.

Here's match:

Converts pattern to a Regexp (if it isn’t already one), then invokes its match method on str. If the second parameter is present, it specifies the position in the string to begin the search.

Note the part about converting. In a regular expression ( and ), among other characters, have significant meaning. You can't use match arbitrarily here. It has a very specific function.

You rarely see .eql? used in actual Ruby code, the convention is simply this:

text_from_page == error_text

The eql? method is primarily intended for internal use. It comes into play when doing comparisons, and when finding things in a container like an Array or Hash.

Faster constant-time string comparison in Ruby

secure_compare (constant time string comparison in Rails)


If you are using Rails (or a standalone ActiveSupport) you can consider using ActiveSupport::SecurityUtils.secure_compare for the constant time string comparison.

Here is an example:

ActiveSupport::SecurityUtils.secure_compare('foo', 'bar')

Also if you are interested in on how it works, please have a look at the source.



Related Topics



Leave a reply



Submit