array = ["Spam is bad", "Ham is good"]
I would like select the element(s) from the array which include(s) the word 'good' and set the string to a new variable. How could I do this?
Since neither answer so far instructs you on how to update the string in the array to the new value, here are some options:
# Find every string matching a criteria and change them
array.select{ |s| s.include? "good" }.each{ |s| s.replace( "bad" ) }
# Find every string matching a pattern and change them
array.grep.replace( "bad" ).each{ |s| s.replace( "bad" ) }
# Find the first string matching a criteria and change it
array.find{ |s| s =~ /good/ }.replace( "bad" )
However, all of the above will change every instance of a string. For example:
jon = Person.new "Johnny B. Goode"
array = [ jon.name, "cat" ]
array.find{ |s| s =~ /good/i }.replace( "bad" )
p array #=> "bad"
p jon #=> #<Person name="bad"> Uh oh...
If you don't want this side effect—if you want to replace the string in the array with a different string, but not change the string itself–then you need to find the index of the item and update that:
# Find the _first_ index matching some criteria and change it
array[ array.index{ |s| s =~ /good/ } ] = "bad"
# Update _every_ item in the array matching some criteria
array[i] = "bad" while i = array.index{ |s| s =~ /good/i }
# Another way to do the above
# Possibly more efficient for very large arrays any many items
indices = array.map.with_index{ |s,i| s =~ /good/ ? i : nil }.compact
indices.each{ |i| array[i] = "bad" }
Finally, the simplest and mostly fastest, without mucking about with indices:
# Create a new array with the new values
new_array = array.map do |s|
if s =~ /good/i # matches "Good" or "good" in the string
"bad"
else
s
end
end
# Same thing, but shorter syntax
new_array = array.map{ |s| s =~ /good/i ? "bad" : s }
# Or, change the array in place to the new values
new_array = array.map!{ |s| s =~ /good/i ? "bad" : s }
map!
sounds like a good choice.
x = ['i', 'am', 'good']
def change_string_to_your_liking s
# or whatever it is you plan to do with s
s.gsub('good', 'excellente!')
end
x.map! {|i| i =~ /good/ ? change_string_to_your_liking(i) : i}
puts x.inspect
There's also a special method for this:
array.grep(/good/) # => ["Ham is good"]
With #grep you can do a lot because it takes a regular expression...
It's almost as you typed your title:
array.select {|s| s.include? "good"}
Here's the doc: http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-select
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With