How to count a string elements' occurrence in another string in ruby?

How can I check how many times a phrase occurs in a string?

For example, let's say the phrase is donut

str1 = "I love donuts!"
#=> returns 1 because "donuts" is found once.
str2 = "Squirrels do love nuts" 
#=> also returns 1 because of 'do' and 'nuts' make up donut
str3 = "donuts do stun me" 
#=> returns 2 because 'donuts' and 'do stun' has all elements to make 'donuts'

I checked this SO that suggests using include, but it only works if donuts is spelled in order.

I came up with this, but it doesn't stop spelling after all elements of "donuts"is spelled. i.e. "I love donuts" #=> ["o", "d", "o", "n", "u", "t", "s"]

def word(arr)
  acceptable_word = "donuts".chars { |name| acceptable_word.include? name.downcase }

How can I check how many occurrences of donuts are there in a given string? No edge cases. Input will always be String, no nil. If it contains elements of donut only it should not count as 1 occurrence; it needs to contain donuts, doesn't have to be in order.



def count_em(str, target) { |c| str.count(c)/target.count(c) }.min


count_em "I love donuts!", "donuts"                      #=> 1
count_em "Squirrels do love nuts", "donuts"              #=> 1
count_em "donuts do stun me", "donuts"                   #=> 2
count_em "donuts and nuts sound too delicious", "donuts" #=> 3
count_em "cats have nine lives", "donuts"                #=> 0
count_em "feeding force scout", "coffee"                 #=> 1
count_em "feeding or scout", "coffee"                    #=> 0

str = ("free mocha".chars*4).shuffle.join
  # => "hhrefemcfeaheomeccrmcre eef oa ofrmoaha "
count_em str, "free mocha"
  #=> 4



str = "feeding force scout"
target = "coffee"

a = target.chars
  #=> ["c", "o", "f", "f", "e", "e"] 
b = a.uniq
  #=> ["c", "o", "f", "e"] 
c = { |c| str.count(c)/target.count(c) }
  #=> [2, 2, 1, 1] 
  #=> 1 

In calculating c, consider the first element of b passed to the block and assigned to the block variable c.

c = "c"

Then the block calculation is

d = str.count(c)
  #=> 2 
e = target.count(c)
  #=> 1
  #=> 2

This indicates that str contains enough "c"'s to match "coffee" twice.

The remaining calculations to obtain c are similar.


If the characters of str matching characters target must be in the same order as those of target, the following regex could be used.

target = "coffee"

r = /#{ target.chars.join(".*?") }/i
  #=> /c.*?o.*?f.*?f.*?e.*?e/i

matches = "xcorr fzefe yecaof tfe erg eeffoc".scan(r)
  #=> ["corr fzefe ye", "caof tfe e"]
  #=> 2

"feeding force scout".scan(r).size
  #=> 0 

The questions marks in the regex are needed to make the searches non-greedy.

The solution is more or less simple (map(&:dup) is used there to avoid inputs mutating):

pattern = 'donuts'
[str1, str2, str3].map(&:dup).map do |s|
  loop.with_index do |_, i|
    break i unless pattern.chars.all? { |c| s.sub!(c, '') }
#⇒ [1, 1, 2]

Here's an approach with two variants, one where the letters must appear in order, and one where order is irrelevant. In both cases the frequency of each letter is respected, so "coffee" must match vs. two 'f' and two 'e' letters, "free mocha" is insufficient to match, lacking a second 'f'.

def sorted_string(string)

def phrase_regexp_sequence(phrase)

def phrase_regexp_unordered(phrase)
    phrase.downcase.gsub(/\W/, '').split('').sort.chunk_while(&:==).map do |bit|

def contains_unordered(phrase, string)

def contains_sequence(phrase, string)

strings = [
  "I love donuts!",
  "Squirrels do love nuts",
  "donuts do stun me",
  "no stunned matches",

phrase = 'donut'

strings.each do |string|
  puts '%-30s %s %s' % [
    contains_unordered(phrase, string),
    contains_sequence(phrase, string)

# => I love donuts!                 true true
# => Squirrels do love nuts         true true
# => donuts do stun me              true true
# => no stunned matches             true false


 ? Convert String to Regexp in Ruby
 ? Array includes string ruby?
 ? How do I check if a string contains a specific word?
 ? How do I check if a string contains a specific word?
 ? How do I check if a string contains a specific word?
 ? PHP - How to check if a string contain any text
 ? PHP - How to check if a string contain any text
 ? PHP - How to check if a string contain any text
 ? PHP - How to check if a string contain any text
 ? How do I check if a string contains a specific word?