Krzynek
Krzynek

Reputation: 83

How to return the whole array instead of a single string

I am trying to return all words which have more than four letters in the below exercise.

def timed_reading(max_length, text)
  var_b = text.split(" ")

  var_b.map do |i|
    if i.length >= max_length
      return i
    end
  end
end

print timed_reading(4,"The Fox asked the stork, 'How is the soup?'")
# >> asked

I seem to get only one word.

Upvotes: 2

Views: 169

Answers (2)

Cary Swoveland
Cary Swoveland

Reputation: 110675

You don't need to first extract all words from the string and then select those having at least four letters. Instead you can just extract the desired words using String#scan with a regular expression.

str = "The Fox asked the stork, 'How is the soup?'? Très bon?"

str.scan /\p{Alpha}{4,}/
  #=> ["asked", "stork", "soup", "Très"]

The regular expression reads, "Match strings containing 4 or more letters". I've used \p{Alpha} (same as \p{L} and [[:alpha:]]) to match unicode letters. (These are documented in Regexp. Search for these expressions there.) You could replace \p{Alpha} with [a-zA-Z], but in that case "Très" would not be matched.

If you wish to also match digits, use \p{Alnum} or [[:alnum:]] instead. While \w also matches letters (English only) and digits, it also matches underscores, which you probably don't want in this situation.

Punctuation can be a problem when words are extracted from the string by splitting on whitespace.

arr = "That   is a cow.".split
  #=> ["That", "is", "a", "cow."]
arr.select { |word| word.size >= 4 }
  #=> ["That", "cow."]

but "cow" has only three letters. If you instead used String#scan to extract words from the string you obtain the desired result.

arr = "That   is a cow?".scan /\p{Alpha}+/
  #=> ["That", "is", "a", "cow"]
arr.select { |word| word.size >= 4 }
  #=> ["That"]

However, if you use scan you may as well use a regular expression to retrieve only words having at least 4 characters, and skip the extra step.

Upvotes: 2

tadman
tadman

Reputation: 211560

If you want to filter a list and select only certain kinds of entries, use the select method:

var_b.select do |i|
  i.length >= max_length
end

Where that's all you need.

The return i in the middle is confusing things, as that breaks out of the loop and returns a single value from the method itself. Remember that in Ruby, unlike others such as JavaScript, return is often implied and doesn't need to be spelled out explicitly.

Blocks don't normally have return in them for this reason unless they need to interrupt the flow and break out of the method itself.

Upvotes: 4

Related Questions