From d313afa48715a680a0bb180f98cdba6ff627fe17 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Fri, 2 May 2025 21:48:04 +0200 Subject: [PATCH] Add `String.count` to count the number of instances of a string. --- lib/std/core/string.c3 | 32 ++++++++++++++++++++++++++++++++ releasenotes.md | 1 + test/unit/stdlib/core/string.c3 | 16 ++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/lib/std/core/string.c3 b/lib/std/core/string.c3 index 6dcc10e89..8adaa10d5 100644 --- a/lib/std/core/string.c3 +++ b/lib/std/core/string.c3 @@ -375,6 +375,38 @@ fn bool String.contains(s, String substr) return @ok(s.index_of(substr)); } +<* + Check how many non-overlapping instances of a substring there is. + + If the substring has zero length, the number of matches is zero. + + @param [in] self : "The string to search" + @param [in] substr : "The string to look for." + @pure + @return "The number of times matched" +*> +fn usz String.count(self, String substr) +{ + usz count = 0; + usz needed = substr.len; + if (needed == 0) return 0; + char first = substr[0]; + while OUTER: (self.len >= needed) + { + foreach (i, c: self[..^needed]) + { + if (c == first && self[i : needed] == substr) + { + count++; + self = self[i + needed..]; + continue OUTER; + } + } + break; + } + return count; +} + <* Find the index of the first incidence of a string. diff --git a/releasenotes.md b/releasenotes.md index 52c2fabf1..c5152fc19 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -10,6 +10,7 @@ - Added `String.quick_ztr` and `String.is_zstr` - std::ascii moved into std::core::ascii. Old _m variants are deprecated, as is uint methods. - Add `String.tokenize_all` to replace the now deprecated `String.splitter` +- Add `String.count` to count the number of instances of a string. ## 0.7.1 Change list diff --git a/test/unit/stdlib/core/string.c3 b/test/unit/stdlib/core/string.c3 index d9b45f88e..9a6bee9ed 100644 --- a/test/unit/stdlib/core/string.c3 +++ b/test/unit/stdlib/core/string.c3 @@ -14,6 +14,22 @@ fn void test_starts_with() assert(!s.starts_with("o")); } +fn void test_count() +{ + String s = "aaabcabd"; + assert(s.count("a") == 4); + assert(s.count("aa") == 1); + assert(s.count("ab") == 2); + assert(s.count("") == 0); + assert(s.count("e") == 0); + String s2 = "abbccc"; + assert(s2.count("a") == 1); + assert(s2.count("b") == 2); + assert(s2.count("c") == 3); + assert(s2.count("ab") == 1); + assert(s2.count(" ") == 0); +} + fn void quick_zstr() { String str = "1234";