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

前端 未结 3 1758
轻奢々
轻奢々 2021-02-01 12:07

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:

strin         


        
3条回答
  •  野性不改
    2021-02-01 12:43

    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:

    string="aaabbccaaaaddbb"
    

    #1

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

    def count_em(string, substring)
      string.scan(/(?=#{substring})/).count
    end
    
    count_em(string,"aa")
     #=> 5
    

    Note:

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

    A positive lookbehind produces the same result:

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

    As well, String#scan can be replaced with String#gsub.

    #2

    Convert to an array, apply Enumerable#each_cons, then join and count:

    def count_em(string, substring)
      string.each_char.each_cons(substring.size).map(&:join).count(substring)
    end
    
    count_em(string,"aa")
      #=> 5
    

    We have:

    enum0 = "aaabbccaaaaddbb".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", "b"]
    
    enum1 = enum0.each_cons("aa".size)
      #=> #: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", "b"]]
    
    c = enum1.map(&:join)
      #=> ["aa", "aa", "ab", "bb", "bc", "cc", "ca",
      #    "aa", "aa", "aa", "ad", "dd", "db", "bb"]
    c.count("aa")
      #=> 5
    

提交回复
热议问题