Finding the difference between strings in Ruby
All of the solutions so far ignore the fact that the second array can also have elements that the first array doesn't have. Chuck has pointed out a fix (see comments on other posts), but there is a more elegant solution if you work with sets:
require 'set'
teamOne = "Billy, Frankie, Stevie, John"
teamTwo = "Billy, Frankie, Stevie, Zach"
teamOneSet = teamOne.split(', ').to_set
teamTwoSet = teamTwo.split(', ').to_set
teamOneSet ^ teamTwoSet # => #<Set: {"John", "Zach"}>
This set can then be converted back to an array if need be.
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"]
Find the first differing character between two Strings in Ruby
Something like this ought to work:
str_a.each_char.with_index
.find_index {|char, idx| char != str_b[idx] } || str_a.size
Edit: It works: http://ideone.com/Ttwu1x
Edit 2: My original code returned nil
if str_a
was shorter than str_b
. I've updated it to work correctly (it will return str_a.size
, so if e.g. the last index in str_a
is 3, it will return 4).
Here's another method that may strike some as slightly simpler:
(0...str_a.size).find {|i| str_a[i] != str_b[i] } || str_a.size
http://ideone.com/275cEU
diff a ruby string or array
diff.rb is what you want, which is available at http://users.cybercity.dk/~dsl8950/ruby/diff.html via internet archive:
http://web.archive.org/web/20140421214841/http://users.cybercity.dk:80/~dsl8950/ruby/diff.html
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
Comparing strings of equal lengths and noting where the differences occur
Here's where I'd start. I'm purposely using different strings to make it easier to see the differences:
str1 = 'jackdaws love my giant sphinx of quartz'
str2 = 'jackdaws l0ve my gi4nt sphinx 0f qu4rtz'
To get the first string's characters:
str1.chars.with_index.to_a - str2.chars.with_index.to_a
=> [["o", 10], ["a", 19], ["o", 30], ["a", 35]]
To get the second string's characters:
str2.chars.with_index.to_a - str1.chars.with_index.to_a
=> [["0", 10], ["4", 19], ["0", 30], ["4", 35]]
There will be a little slow down as the strings get bigger, but it won't be bad.
EDIT: Added more info.
If you have an arbitrary number of strings, and need to compare them all, use Array#combination
:
str1 = 'ACCT'
str2 = 'ATCT'
str3 = 'AGCT'
require 'pp'
pp [str1, str2, str3].combination(2).to_a
>> [["ACCT", "ATCT"], ["ACCT", "AGCT"], ["ATCT", "AGCT"]]
In the above output you can see that combination
cycles through the array, returning the various n
sized combinations of the array elements.
pp [str1, str2, str3].combination(2).map{ |a,b| a.chars.with_index.to_a - b.chars.with_index.to_a }
>> [[["C", 1]], [["C", 1]], [["T", 1]]]
Using combination's output you could cycle through the array, comparing all the elements against each other. So, in the above returned array, in the "ACCT" and "ATCT" pair, 'C' was the difference between the two, located at position 1 in the string. Similarly, in "ACCT" and "AGCT" the difference is "C" again, in position 1. Finally for 'ATCT' and 'AGCT' it's 'T' at position 1.
Because we already saw in the longer string samples that the code will return multiple changed characters, this should get you pretty close.
What's the difference between String.new and a string literal in Ruby?
==
checks for equal content.
equal?
checks for equal identity.
a = "hello"
b = "hello"
a == b # => true
a.equal?(b) # => false
In Ruby string literals are not immutable and thus creating a string and using a literal are indeed the same. In both cases Ruby creates a new string instance each time the expressions in evaluated.
Both of these are thus the same
10.times { String.new }
# is the same as
10.times { "" }
Let's verify this
10.times { puts "".object_id }
Prints 10 different numbers
70227981403600
70227981403520
70227981403460
...
Why? Strings are by default mutable and thus Ruby has to create a copy each time a string literal is reached in the source code. Even if those literals are usually rarely modified in practice.
Thus a Ruby program typically creates an excessive amount short-lived string objects, which puts a huge strain on garbage collection. It is not unusual that a Rails app creates 500,000 short-lived strings just to serve one request and this is one of the main performance bottlenecks of scaling Rails to millions or even 100 millions of users.
To address that Ruby 2.3 introduced frozen string literals, where all string literals default to being immutable. Since this is not backwards compatible it is opt-in with a pragma
# frozen_string_literal: true
Let's verify this too
# frozen_string_literal: true
10.times { puts "".object_id }
Prints the same number 10 times
69898321746880
69898321746880
69898321746880
...
Fun fact, setting a key in a hash also creates a copy of a string
str = "key"
hash = {}
hash[str] = true
puts str.object_id
puts hash.keys.first.object_id
Prints two different numbers
70243164028580
70243132639660
Related Topics
Is There an Easy-To-Use Ftp Library for Ruby
Append Row to CSV File Ruby 1.9 CSV Lib
Ruby, How to Add a Param to an Url That You Don't Know If It Has Any Other Param Already
How to Create a Folder (If Not Present) with Logger.New
How to Download a File Over Http Using Ruby
Are There "Rules" for Ruby Syntactic Sugar
Solving Dependency Constraints
Ruby - No Pid Found in Tmp/Pids/Thin.Pid (Thin::Pidfilenotfound)
Get Time from Datetime Variable in Ruby
Ruby on Rails Looks for CSS in Assets Instead of Public/Stylesheets
What's the Easiest Way to Send a Message Through Outlook with Ruby
Error When Installing Ruby 2.1.3 with Rvm
Undefined Method 'Devise' When Including User Model Outside Rails
Ruby Imap "Changes" Since Last Check
What the Purpose of Bind/Unbind Methods in Ruby
Rspec Load Time Incredible Long on Os X