Find all pairs of unique indices in a list such that the concatenation of the two words is a palindrome The task


  Given a list of words, find all pairs of unique indices such that the
  concatenation of the two words is a palindrome.
  
  For example, given the list ["code", "edoc", "da", "d"], return 
  [(0, 1), (1, 0), (2, 3)].


const lst = ["code", "edoc", "da", "d"];


My functional solution

const findPalindromePairs = lst =&gt; {
  const isPalindrome = str =&gt; str === [...str].reverse().join("");
  return lst.reduce((pairs, w1, i) =&gt; {
    return [...pairs, ...lst.reduce((match, w2, j) =&gt; {
      if (i !== j &amp;&amp; isPalindrome(`${w1}${w2}`)) { match.push([i,j]); }
      return match;
    }, [])];
  }, []);
};

console.log(findPalindromePairs(lst));


My imperative solution

function findPalindromePairs2 (lst) {
  const len = lst.length;
  const pairs = [];

  const isPalindrome = str =&gt; str === [...str].reverse().join("");
  for (let i = 0; i &lt; len; i++) {
    for (let j = 0; j &lt; len; j++) {
      if (i !== j &amp;&amp; isPalindrome(lst[i] + lst[j])) { pairs.push([i,j]); }
    }
  }
  return pairs;
}

console.log(findPalindromePairs2(lst));
I don't really see anything that jumps out as an obvious simplification. I looked online for other code for this task and only found one in python which uses the same basic algorithm. 

The only suggestion I have is for readability, the name match in the functional solution might be slightly confusing for anyone reading the code. Perhaps a more appropriate name would be something like subMatches.

I did notice that the functional solution concatenates the strings with a template literal, while the imperative solution uses traditional string concatenation. Why not just use the traditional technique in the functional solution? The results of this jsPerf show negligible differences between the two approaches.