How do I compare "string1" with ["string1"]? The following results in false:
params[:abc] # => "neon green"
#abc # => ["neon green"]
params[:abc] == #abc # => false
You could use Array#include?. However, this will return true if the array contains "string1" and "string2".
["string1"].include?("string1") # => true
["string1", "string2"].include?("string1") # => true
In the event you want to compare the array contains only the string, I'd recommend using the Array method, which converts the parameters provided to it into an array.
Array(["string1"]) == Array("string1") # => true
Array(["string1", "string2"]) == Array("string1") # => false
How it works:
Array(["string1"]) # => ["string1"]
Array("string1") # => ["string1"]
Array(nil) # => []
Another option - put the string inside an array of itself:
[params[:abc]] == #abc # => true
Or, if you don't know which one is an array, use an array-splat ([*]) combination:
[*params[:abc]] == [*#abc] # => true
Array-splat will work in a similar fashion to #Jkarayusuf's Array():
[*["string1"]] # => ["string1"]
[*"string1"] # => ["string1"]
[*nil] # => []
you can wrap the second one in an array, or extract the string from the array
[params[:abc]] == #abc
or
params[:abc] == #abc.first
I kinda like the first one more
I'd do:
#abc = #abc.join('')
#=> "neon green"
if params[:abc] == #abc
do thing 1
else
do thing 2
end
Try this
params[:abc].in? #abc
Related
I need to check if given String includes a string or regex. If it does, it should return true, otherwise - false. How can I do it?
I have:
def method(string)
if #text.match(/#{string}/)
true
else
false
end
end
But I'm not sure if it's a proper way.
Consider this:
#text = 'foobar'
def method1(string)
if #text.match(/#{string}/)
true
else
false
end
end
That can be reduced to:
def method2(string_or_regex)
if #text[string_or_regex]
true
else
false
end
end
String's [] method allows us to pass in a string or a pattern. If it's a string, the method uses it for a fixed-string/in-string search. If a pattern is passed in it returns the matching text.
However, Ruby is more friendly than this. We don't have to tell it to return a true or false value conditionally. In Ruby, a nil or false value is treated as false, and anything else is "truethy". We can convert a value to true/false using !!, which is double boolean "not":
true # => true
'foo' # => "foo"
false # => false
nil # => nil
!true # => false
!'foo' # => false
!false # => true
!nil # => true
!!true # => true
!!'foo' # => true
!!false # => false
!!nil # => false
Knowing that, and that String's [] returns a nil if not found, or the matching text if found:
'foo'['foo'] # => "foo"
'foo'['bar'] # => nil
we can reduce the original method to:
def method3(string_or_regex)
!!#text[string_or_regex]
end
Here's what happens testing each of the methods above:
method1('foo') # => true
method1('baz') # => false
method2('foo') # => true
method2(/foo/) # => true
method2('baz') # => false
method2(/baz/) # => false
method3('foo') # => true
method3(/foo/) # => true
method3('baz') # => false
method3(/baz/) # => false
You have to be careful interpolating a regular expression object into another regular expression:
string = /foo/
/#{string/ # => /(?-mix:foo)/
The (?-mix: are the pattern flags being inserted inside another pattern, which can open your pattern to all sorts of weird behaviors and create extremely hard to find bugs. Instead, I strongly recommend using the source method if you're going to do that, which results in the original pattern being inserted:
/#{string.source}/ # => /foo/
Code with single line:
!#text.match(/#{string}/).nil?
This is my code:
fred = {
'age' => 63,
'gender' => 'male',
'favorite painters' => ['Monet', 'Constable', 'Da Vinci']
}
fred.delete_if { |k,v| k.match(/[a]/) }
puts fred
The result shows {"gender"=>"male"}.
If I change the code to
fred.delete_if { |k,v| k.include?(/[a]/) }
it won't work.
Can anyone explain why to me?
String#match takes a regex object (or a regex pattern string) as the parameter while String#included? takes a string as the parameter.
You should use:
fred.delete_if { |k,v| k.include?('a') }
For more info, see the document.
.include? returns boolean true/false, and expects a string as input.
.match returns information about the match in the form of MatchData (or nil if nothing was matched), and accepts a string or regular expression.
Everyone is recommending using include? for a literal match. I prefer a different syntax that accomplishes the same thing:
"foo".include?("o") # => true
"foo"["o"] # => "o"
"foo".include?("a") # => false
"foo"["a"] # => nil
In Ruby, anything that is not nil or false is considered true, so, for boolean tests the above tests are equivalent if you get a value or true, or if you get false or nil.
If you absolutely must have a boolean result, use the !! ("not not") trick which nicely converts a "truthy" value to its boolean complement, then back to that value's boolean complement.
true # => true
false # => false
'a' # => "a"
nil # => nil
!true # => false
!false # => true
!'a' # => false
!nil # => true
!!true # => true
!!false # => false
!!'a' # => true
!!nil # => false
Which lets us do:
!!"foo"["o"] # => true
!!"foo"["a"] # => false
This results in more compact code, which might not be what your particular coding-style wants. It pushes the Ruby code toward Perl or C code so weigh the compactness with readability and pick which style you want.
See String#[] for more information.
Is there a helper method to delete all items from an array and return those items in ruby?
For example,
array = [{:a=>1, :b=>2},{:a=>3,:b=>4},{:a=>5,:b=>6}]
and I want to delete all the array elements and return them so I can do some processing on those elements?
array = [{:a=>1, :b=>2},{:a=>3,:b=>4},{:a=>5,:b=>6}]
while element = array.pop do
# process element however you like...
end
array # => []
or use shift rather than pop if order matters to you.
Do as below using Array#shift to delete the array content in one shot and return its elements:
array = [{:a=>1, :b=>2},{:a=>3,:b=>4},{:a=>5,:b=>6}]
array.shift(array.size)
# => [{:a=>1, :b=>2}, {:a=>3, :b=>4}, {:a=>5, :b=>6}]
array
# => []
If you want to delete one by one,you can do as below using Array#delete_if:
array = [{:a=>1, :b=>2},{:a=>3,:b=>4},{:a=>5,:b=>6}]
array.delete_if do |e|
#do your work with e
true
end
array # => []
Another approach is do your work first with the array and then delete all the elements from the array:
array = [{:a=>1, :b=>2},{:a=>3,:b=>4},{:a=>5,:b=>6}]
array.each do |e|
#do your work with e
end
array.clear
array # => []
I have an Excel column containing part numbers. Here is a sample
As you can see, it can be many different datatypes: Float, Int, and String. I am using roo gem to read the file. The problem is that roo interprets integer cells as Float, adding a trailing zero to them (16431 => 16431.0). I want to trim this trailing zero. I cannot use to_i because it will trim all the trailing numbers of the cells that require a decimal in them (the first row in the above example) and will cut everything after a string char in the String rows (the last row in the above example).
Currently, I have a a method that checks the last two characters of the cell and trims them if they are ".0"
def trim(row)
if row[0].to_s[-2..-1] == ".0"
row[0] = row[0].to_s[0..-3]
end
end
This works, but it feels terrible and hacky. What is the proper way of getting my Excel file contents into a Ruby data structure?
def trim num
i, f = num.to_i, num.to_f
i == f ? i : f
end
trim(2.5) # => 2.5
trim(23) # => 23
or, from string:
def convert x
Float(x)
i, f = x.to_i, x.to_f
i == f ? i : f
rescue ArgumentError
x
end
convert("fjf") # => "fjf"
convert("2.5") # => 2.5
convert("23") # => 23
convert("2.0") # => 2
convert("1.00") # => 1
convert("1.10") # => 1.1
For those using Rails, ActionView has the number_with_precision method that takes a strip_insignificant_zeros: true argument to handle this.
number_with_precision(13.00, precision: 2, strip_insignificant_zeros: true)
# => 13
number_with_precision(13.25, precision: 2, strip_insignificant_zeros: true)
# => 13.25
See the number_with_precision documentation for more information.
This should cover your needs in most cases: some_value.gsub(/(\.)0+$/, '').
It trims all trailing zeroes and a decimal point followed only by zeroes. Otherwise, it leaves the string alone.
It's also very performant, as it is entirely string-based, requiring no floating point or integer conversions, assuming your input value is already a string:
Loading development environment (Rails 3.2.19)
irb(main):001:0> '123.0'.gsub(/(\.)0+$/, '')
=> "123"
irb(main):002:0> '123.000'.gsub(/(\.)0+$/, '')
=> "123"
irb(main):003:0> '123.560'.gsub(/(\.)0+$/, '')
=> "123.560"
irb(main):004:0> '123.'.gsub(/(\.)0+$/, '')
=> "123."
irb(main):005:0> '123'.gsub(/(\.)0+$/, '')
=> "123"
irb(main):006:0> '100'.gsub(/(\.)0+$/, '')
=> "100"
irb(main):007:0> '127.0.0.1'.gsub(/(\.)0+$/, '')
=> "127.0.0.1"
irb(main):008:0> '123xzy45'.gsub(/(\.)0+$/, '')
=> "123xzy45"
irb(main):009:0> '123xzy45.0'.gsub(/(\.)0+$/, '')
=> "123xzy45"
irb(main):010:0> 'Bobby McGee'.gsub(/(\.)0+$/, '')
=> "Bobby McGee"
irb(main):011:0>
Numeric values are returned as type :float
def convert_cell(cell)
if cell.is_a?(Float)
i = cell.to_i
cell == i.to_f ? i : cell
else
cell
end
end
convert_cell("foobar") # => "foobar"
convert_cell(123) # => 123
convert_cell(123.4) # => 123.4
How do I a string against a regex such that it will return true if the whole string matches (not a substring)?
eg:
test( \ee\ , "street" ) #=> returns false
test( \ee\ , "ee" ) #=> returns true!
Thank you.
You can match the beginning of the string with \A and the end with \Z. In ruby ^ and $ match also the beginning and end of the line, respectively:
>> "a\na" =~ /^a$/
=> 0
>> "a\na" =~ /\Aa\Z/
=> nil
>> "a\na" =~ /\Aa\na\Z/
=> 0
This seems to work for me, although it does look ugly (probably a more attractive way it can be done):
!(string =~ /^ee$/).nil?
Of course everything inside // above can be any regex you want.
Example:
>> string = "street"
=> "street"
>> !(string =~ /^ee$/).nil?
=> false
>> string = "ee"
=> "ee"
>> !(string =~ /^ee$/).nil?
=> true
Note: Tested in Rails console with ruby (1.8.7) and rails (3.1.1)
So, what you are asking is how to test whether the two strings are equal, right? Just use string equality! This passes every single one of the examples that both you and Tomas cited:
'ee' == 'street' # => false
'ee' == 'ee' # => true
"a\na" == 'a' # => false
"a\na" == "a\na" # => true