7
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?

0

4 Answers 4

16

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 }
Sign up to request clarification or add additional context in comments.

Comments

2

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

3 Comments

Good answer, but note that the OP never said anything about changing the string (gsub), but replacing it wholesale.
@Phrogz the question is very unclear about what should be set to what
Maprihoda is correct. The OP says to set the string to a new variable. For all we know that could mean create an integer value from the string. It could indeed require replacement, but this is not explicitly stated. Due to the ambiguity, I made no assumption on the exact intentions of variable modification and provided a method whose contents could easily be modified to his liking. Note the name of the method change_string_to_your_liking and the comment # or whatever it is you plan to do with s.
2

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...

3 Comments

This doesn't solve the issue of setting the array element to another value.
@maprihoda Note that while grep is convenient, nothing prevents you from using a regex with select or find (as in my answer). Indeed, you can do much more with the block methods, e.g. select{ |s| s=~/good/i && s.length > 3 }.
@Phrogz much more in terms of regular expression; nevertheless, you're right, you can do a lot with select, the second select example in your comment illustrates it very nicely
1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.