TicTacToe solver in JavaScript I come more from a frontend background and have been reading up on more backend approaches and algorithms while solving a TicTacToe grid to see if there are any wins normally, I'd probably use something like this

for (let i = 0; i &lt; rows; i++) {
    if (arr[i][0] === arr[i][1] &amp;&amp; arr[i][0] === arr[i][2]) {


but with what I've been studying, I thought it'd be better to use a map and iterate through them instead



'use strict';

const board = [
  ['x','x','x'],
  ['x','o','o'],
  ['x','x','x']
]

const matches = [
  [1,4,7],
  [2,5,8],
  [3,6,9],
  [1,2,3],
  [4,5,6],
  [7,8,9],
  [1,5,9],
  [3,5,7]
]

const solver = (board, matches) =&gt; {
  // build map
  let counter = 1;
  const map = {};
  
  // convert array to object
  for (let row of board) {
    for (let char of row) {
      map[counter] = char;
      counter++;
    }
  }

  for (let match of matches) {
    // create a new array with the values
    const arr = [...map[match[0]],map[match[1]],map[match[2]]];
    // check for duplicates
    const arr2 = [...new Set(arr)].join("");
    // console log if length is 1
    if (arr2.length === 1) console.log(`match found at set: ${match}`)
  }
}

solver(board, matches)




Is this efficient? Is there a better way of doing this?

It looks a lot cleaner than

if (arr[i][0] === arr[i][1] &amp;&amp; arr[i][0] === arr[i][2])


for sure, but then again, that itself could have probably been designed more efficiently.

Is there a better way to generate the coordinates dynamically?
you can simplify this block a little:

for (let row of board) {
    for (let char of row) {
         map[counter] = char;
         counter++;
    }
}


into:

const map = board.flat();

You can generate matches pseudo-automatically which simultaneously improve readability

function generateMatches() {
     function simpleRange(upTo) {
          return new Array(upTo).fill(true).map((_, index) =&gt; index);
     }

     function customRange(start, step, length) {
          return simpleRange(length).map(index =&gt; start + index * step);
     }

     function horizontalRow(top) {
          return customRange(3 * top, 1, 3);
     }

     function verticalRow(left) {
          return customRange(left, 3, 3);
     }

     function progressingDiagonal() {
          return customRange(0, 4, 3);
     }

     function regressingDiagonal() {
          return customRange(2, 2, 3);
     }

     const matches = [];
     for (let top = 0; top &lt; 3; ++top) {
          matches.push(horizontalRow(top));
     }
     for (let left = 0; left &lt; 3; ++left) {
          matches.push(verticalRow(left));
     }
     matches.push(progressingDiagonal());
     matches.push(regressingDiagonal());
     return matches;
}




  Warning! I assumed starting at 0 index



Don't use console.log(...); in solve function. Try to return list of matches instead and use user interface API outside of it. It will allow you to write some automatic (for instance unit) tests for your code (using Motcha, Jasmine, etc... depending on your target technology)
General advices:


Use better names for variables: map -> flatBoard, arr -> row, arr2 -> reducedRow
Split your code into smaller functions for each step, for instance:

const arr2 = [...new Set(arr)].join("");


into:

function reduceRow(array) {
     return [...new Set(array)].join("");
}
const reducedRow = reduceRow(row);


Your original question is about performance. Let just start it now:


IMHO you don't need to convert Set into array into string to test its size. Use something like this instead: 
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/size

function rowDiversity(array) {
     return new Set(array).size;
}
const rowDiversity = rowDiversity(row);

Not sure if destructuring operator is needed at all at previous line too (most likely its performance impact is already neutral) But I would write this instead anyway:

function fetchRow(flattenBoard, match) {
     return match.map(index =&gt; flattenBoard[index]);
}
const row = fetchRow(flattenBoard, match);