Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby: How to count the number of times a string appears in another string?

Tags:

string

ruby

count

I'm trying to count the number of times a string appears in another string.

I know you can count the number of times a letter appears in a string:

string = "aabbccddbb" string.count('a') => 2 

But if I search for how many times 'aa' appears in this string, I also get two.

string.count('aa') => 2 

I don't understand this. I put the value in quotation marks, so I'm searching for the number of times the exact string appears, not just the letters.

like image 546
Johnson Avatar asked Sep 19 '14 16:09

Johnson


People also ask

How do I count how many times a string appears in another string?

Python String count() function is an inbuilt function in python programming language that returns the number of occurrences of a substring in the given string. Parameters: The count() function has one compulsory and two optional parameters.

How do you count strings in Ruby?

Ruby | String count() Method In this method each parameter defines a set of characters to which is to be counted. The intersection of these sets defines the characters to count in the given string. Any other string which starts with a caret ^ is negated. Parameters: Here, str is the given string.

How do you find the number of occurrences in a string?

count() One of the built-in ways in which you can use Python to count the number of occurrences in a string is using the built-in string . count() method. The method takes one argument, either a character or a substring, and returns the number of times that character exists in the string associated with the method.

How do you use count in Ruby?

Ruby | Array count() operation Array#count() : count() is a Array class method which returns the number of elements in the array. It can also find the total number of a particular element in the array. Syntax: Array. count() Parameter: obj - specific element to found Return: removes all the nil values from the array.


2 Answers

Here are a couple of ways to count the numbers of times a given substring appears in a string (the first being my preference). Note (as confirmed by the OP) the substring 'aa' appears twice in the string 'aaa', and therefore five times in:

str = "aaabbccaaaaddbab" 

#1

Use String#scan with a regex that contains a positive lookahead that looks for the substring:

def count_em(str, substr)   str.scan(/(?=#{substr})/).count end 
count_em(str,"aa")   #=> 5 count_em(str,"ab")   #=> 2 

Note:

"aaabbccaaaaddbab".scan(/(?=aa)/)   #=> ["", "", "", "", ""] 

A positive lookbehind produces the same result:

"aaabbccaaaaddbab".scan(/(?<=aa)/)   #=> ["", "", "", "", ""] 

As well, String#scan could be replaced with the form of String#gsub that takes one argument (here the same regular expression) and no block, and returns an enumerator. That form of gsub in unusual in that has nothing to do with character replacement; it simply generates matches of the regular expression.

#2

Convert to an array, apply String#each_char then Enumerable#each_cons, then Enumerable#count:

def count_em(str, substr)   subarr = substr.chars   str.each_char      .each_cons(substr.size)      .count(subarr) end 
count_em(str,"aa")   #=> 5 count_em(str,"ab")   #=> 2 

We have:

subarr = "aa".chars   #=> ["a", "a"] enum0 = "aaabbccaaaaddbab".each_char   #=> #<Enumerator: "aaabbccaaaaddbab":each_char> 

We can see the elements that will generated by this enumerator by converting it to an array:

enum0.to_a   #=> ["a", "a", "a", "b", "b", "c", "c", "a", "a", "a",   #    "a", "d", "d", "b", "a", "b"]  enum1 = enum0.each_cons("aa".size)   #=> #<Enumerator: #<Enumerator:   #      "aaabbccaaaaddbab":each_char>:each_cons(2)>  

Convert enum1 to an array to see what values the enumerator will pass on to map:

enum1.to_a   #=> [["a", "a"], ["a", "a"], ["a", "b"], ["b", "b"], ["b", "c"],   #    ["c", "c"], ["c", "a"], ["a", "a"], ["a", "a"], ["a", "a"],    #    ["a", "d"], ["d", "d"], ["d", "b"], ["b", "a"],   #    ["a", "b"]]   enum1.count(subarr)   #=> enum1.count(["a", "a"])   #=> 5 
like image 77
Cary Swoveland Avatar answered Sep 23 '22 11:09

Cary Swoveland


It's because the count counts characters, not instances of strings. In this case 'aa' means the same thing as 'a', it's considered a set of characters to count.

To count the number of times aa appears in the string:

string = "aabbccddbb" string.scan(/aa/).length # => 1 string.scan(/bb/).length # => 2 string.scan(/ff/).length # => 0 
like image 27
tadman Avatar answered Sep 21 '22 11:09

tadman