16

This is an attempt in a tic tac toe game app. I have two arrays playerMoves and winningCombinations. Like this.

var playerMoves= [0,1,4];
var winningCombinations = [
        [0,1,2],[3,4,5],[6,7,8],
        [0,3,6],[1,4,7],[2,5,8],
        [0,4,8],[2,4,6]
      ];

I need to filter the winningCombination array such that at-least and at-most two values of playerMoves array matches with each array in winningCombination.

findPossibleMove(playerMoves);
// should return [[0,1,2],[1,4,7], [0,4,8] ]

My attempt

function findPossibleMove(arr){
  var found = 0;
  return arr.forEach((item)=>{
    winningCombinations.map((obj)=>{
      if(obj.indexOf(item) !== -1) {
        found++;
      }
      if(found===2){
        return obj;
      }        
    })
  })      
}

3 Answers 3

12

Three simple steps:

  • Use indexOf function to check, if specified element from the subarray of winningCombinations array is present in the playerMoves array.
  • If so - filter it out with Array#filter function.
  • If the returned, filtered subarray has length equal to 2, it means that two (no more, nor less) elements have appeared - it fulfills our condition - filter it once again with yet another Array#filter.

let playerMoves = [0, 1, 4];
let winningCombinations = [
  [0, 1, 2],
  [3, 4, 5],
  [6, 7, 8],
  [0, 3, 6],
  [1, 4, 7],
  [2, 5, 8],
  [0, 4, 8],
  [2, 4, 6],
];

let res = winningCombinations.filter(v => v.filter(c => {
  return playerMoves.indexOf(c) > -1;
}).length == 2);
  
  console.log(JSON.stringify(res));

Sign up to request clarification or add additional context in comments.

1 Comment

how would you go about instead of filtering out the none matching once, replacing them. so if i have [['WA', 0], [OR, 0] and the other array is [['WA', 1], [OR, 0], I want WA in the first array to be replaces with the WA value in the second array.
3

You can use filter and includes to achieve that:

var playerMoves= [0,1,4];
var winningCombinations = [
  [0,1,2],[3,4,5],[6,7,8],
  [0,3,6],[1,4,7],[2,5,8],
  [0,4,8],[2,4,6]
];

var filteredCombinations = winningCombinations.filter((combination) =>
  combination.filter(x => playerMoves.includes(x)).length === 2);

console.log(filteredCombinations);

Comments

1

since we have to check with the length (matched item) in each filtered array, how about skipping creation of filtered array against array and reducing it to a number of matched element and check directly with that instead of the length?

let playerMoves = [0, 1, 4];
let winningCombinations = [
  [0, 1, 2],
  [3, 4, 5],
  [6, 7, 8],
  [0, 3, 6],
  [1, 4, 7],
  [2, 5, 8],
  [0, 4, 8],
  [2, 4, 6],
];
let res = winningCombinations.filter(a=> a.reduce((r, v) => r + playerMoves.includes(v), 0)==2);

console.log('matching array: ', res)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.