javascript

Count How Many Substrings in a String JavaScript

Cover Image for Count How Many Substrings in a String JavaScript
6 min read
#javascript

When working with JavaScript, you may encounter situations where you need to count the number of substrings within a string. Whether you're building a search feature, analyzing text data, or creating tools that require text processing, understanding how to count substrings efficiently is essential. In this blog, we’ll dive into various techniques to count substrings in JavaScript, with clear examples, friendly explanations, and a few optimization tips to help you.

What Do We Mean by Count Substrings?

In this context, count substrings means identifying how many times a specific substring (a smaller part of a string) appears in a larger string.

js
const text = "hellohello"; const substring = "hello";

In the above example, the substring "hello" appears twice in the string "hellohello". The goal is to write JavaScript code that counts such occurrences.

Approaches to Counting Substrings in JavaScript

Let’s break this problem down into practical solutions, covering various approaches to cater to different scenarios.

1. Using a Loop to Count Substrings

A straightforward way to count substrings is to loop through the string manually and check for matches. This approach gives you full control over the process.

js
function countSubstrings(text, substring) { let count = 0; let index = 0; while ((index = text.indexOf(substring, index)) !== -1) { count++; index += substring.length; // Move past the current match } return count; } // Test the function const text = "hellohellohello"; const substring = "hello"; console.log(countSubstrings(text, substring)); // Output: 3

How It Works:

  • We use the indexOf() method to find the first occurrence of the substring.
  • Each time a match is found, we increment the count and move the index forward by the length of the substring.
  • The loop continues until no more matches are found (indexOf() returns -1).

Limitations:

  • Can become slower for very large strings due to repeated indexOf() calls.

2. Using Regular Expressions (Regex)

Regular expressions are a powerful way to search for patterns in strings. In JavaScript, you can use the match() method with a global regex to count occurrences of a substring.

js
function countSubstringsWithRegex(text, substring) { const regex = new RegExp(substring, "g"); const matches = text.match(regex); return matches ? matches.length : 0; } // Test the function const text = "abcabcabc"; const substring = "abc"; console.log(countSubstringsWithRegex(text, substring)); // Output: 3

How It Works:

  • A global regular expression (/g) is created for the substring.
  • The match() method returns an array of all matches or null if none are found.
  • The length of the matches array represents the count of substrings.

Limitations:

  • Slightly more complex to set up compared to indexOf().

3. Splitting the String

Another approach is to split the string using the substring as the delimiter. The number of resulting parts minus one gives the count of the substring.

js
function countSubstringsWithSplit(text, substring) { return text.split(substring).length - 1; } // Test the function const text = "banana"; const substring = "na"; console.log(countSubstringsWithSplit(text, substring)); // Output: 2

How It Works:

  • The split() method splits the string wherever the substring is found.
  • The resulting array length minus one gives the count of matches.

Limitations:

Not ideal for overlapping substrings (e.g., counting "aaa" in "aaaa").

4. Handling Overlapping Substrings

In cases where substrings overlap, the previous methods won’t work correctly. For example, counting "aaa" in "aaaa" should yield 2, but the above solutions would return 1. To handle overlapping substrings, you need a custom loop that checks every possible position:

js
function countOverlappingSubstrings(text, substring) { let count = 0; for (let i = 0; i <= text.length - substring.length; i++) { if (text.substring(i, i + substring.length) === substring) { count++; } } return count; } // Test the function const text = "aaaa"; const substring = "aaa"; console.log(countOverlappingSubstrings(text, substring)); // Output: 2

How It Works:

  • Use a for loop to iterate through each position in the string.
  • Extract a substring of the same length as the target and compare it.
  • Increment the count if there’s a match.

Limitations:

  • Slightly more verbose.

Comparing Performance of Methods

When choosing a method, it’s essential to consider the size of your string and whether substrings overlap.

MethodOverlap SupportPerformanceBest Use Case
indexOf with loopNoFastGeneral-purpose substring counting
Regular ExpressionsNoModeratePattern-based or non-overlapping cases
split() methodNoFastSimple, non-overlapping scenarios
Custom loop (overlap)YesModerateCounting overlapping substrings

Advanced Tips

  1. Case Sensitivity: By default, these methods are case-sensitive. To make them case-insensitive, you can convert both the text and substring to lowercase:
js
text.toLowerCase(); substring.toLowerCase();
  1. Special Characters in Regex: If your substring contains special characters, escape them in the regex:
js
const escapedSubstring = substring.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
  1. Performance Optimization: For very large strings, consider splitting the work into chunks or using Web Workers for multi-threading. A more efficient approach is to split the string into smaller chunks, process each chunk individually, and then combine the results. This technique is often referred to as "divide and conquer".
js
function countSubstringsInChunks(text, substring, chunkSize = 10000) { let count = 0; // Process the text in chunks for (let i = 0; i < text.length; i += chunkSize) { // Extract the current chunk const chunk = text.slice(i, i + chunkSize + substring.length - 1); // Count substrings in the chunk using the basic indexOf approach let index = 0; while ((index = chunk.indexOf(substring, index)) !== -1) { count++; index += substring.length; } } return count; } // Test the function const largeText = "abc".repeat(100000); // A very large string const substring = "abc"; console.log(countSubstringsInChunks(largeText, substring)); // Output: 100000

Conclusion

Counting substrings in JavaScript is a versatile task with multiple approaches to suit different needs. From using indexOf and regex to handling overlapping substrings with a custom loop, you now have a comprehensive toolkit for tackling this problem. Choose the method that best fits your scenario, and don’t forget to optimize for readability and performance.

Follow and Support me on Medium and Patreon. Clap and Comment on Medium Posts if you find this helpful for you. Thanks for reading it!!!