Sherlock and Anagrams in Javascript I am trying to solve a Hackerrank problem Sherlock and Anagrams. I think my code is valid but somehow times out for some of the test cases. Any tips on how to improve its performance? Critique unrelated to performance is welcome as well!
Here is my main method which gets a string as an input and returns an integer that represents the number of pairs of substrings of the string that are anagrams of each other:
function sherlockAndAnagrams(s) {

    let substrings = [];
    let pairs = [];

    // get all substrings
    for (let i = 0; i &lt; s.length+1; i++) {
        for (let j = i+1; j &lt; s.length+1; j++) {
            substrings.push(s.substring(i, j));
        }
    }
    
    // sort substrings so they can be compared using ===
    substrings = substrings.map(sub =&gt; [...sub].sort().join(&quot;&quot;));

    // count them by comparing each with each skipping the ones with different length
    return substrings.reduce((counter, sub, index, arr) =&gt; {
        return counter += arr.reduce((acc, item, jndex) =&gt; {
            if (sub.length === item.length &amp;&amp; sub === item &amp;&amp; index !== jndex) {
                let uid = [index, jndex].sort().join(&quot;&quot;);
                if (!pairs.includes(uid)) {
                    acc++;
                    pairs.push(uid);
                }
            }
            return acc;
        }, 0);
    }, 0);
}

Here is a shortened version of the problem description as additional context:

Two strings are anagrams of each other if the letters of one string can be rearranged to form the other string. Given a string, find the number of pairs of substrings of the string that are anagrams of each other.
sherlockAndAnagrams has the following parameter: s: a string
It must return an integer that represents the number of anagrammatic pairs of substrings in s. For each query, return the number of unordered anagrammatic pairs.
comparing each with each means the quadratic time complexity, and skipping the ones with different length does not improve the bottomline.

Sort the set of (sorted) substrings, and the anagrams will form contiguous runs. The run of length \$k\$ produces \$\dfrac{k(k-1)}{2}\$ pairs.



Example:

An original array:

ab
cde
xy
dec
ba
ced


After each string has been sorted, it becomes

ab
cde
xy
cde
ab
cde


Now, after the entire array is sorted lexicographically, it becomes

ab
ab
cde
cde
cde
xy


The ab, ab and cde, cde, cde form the contiguous (that is, uninterrupted) runs, of length 2 and 3 respectively.