Home > Software engineering >  Tick Tack Toe: Filter multidimensional array in JavaScript
Tick Tack Toe: Filter multidimensional array in JavaScript

Time:05-18

I am learning to filter nested arrays in javascript and I believe this example can help me to understand it better. below is the object.

const game = () => {
return {
    player1: {
        username: 'ABC',
        playingAs: 'X'
    },
    player2: {
        username: 'XYZ',
        playingAs: '0'
    },
    board: 
        [
            ['✓', null, 'X'],
            ['X', '✓', null],
            ['✓', null, 'X']
        ]   

   }
};

my code is below

const {player1: {username: PlayerA, playingAs:PlayerAMark}, player2: {username: PlayerB, playingAs:PlayerBMark}} = game();
const {board: board} = game();

//is there any efficient way to do it without a loop using a filter?
for (const item in board) {
    //One approach which comes to my mind is to loop. but that is what I don't think would be a learning curve for me.

}

I am trying something like this

const array = board;
for (const item in board) {
    console.log(array.filter(innerArray => innerArray[item] !== 'X'));
}

I am focused on implementing some efficient way that can help me to return

Player1 marked 'X' at 3,1,3 and
Player 2 marked '0' at location at 0,2,1

I am only stuck with filtering this board multidimensional array.

I appreciate your help on this.

CodePudding user response:

You can also use reduce function. We can have the desired output using this code:

function printForPlayer(player, board) {
var indexes = board.reduce((acc,row)=>[...row.reduce((acc2,item,index) => item==player.playingAs ? [...acc2,index 1] : acc2, []),...acc], [])
console.log(`${player.username} marked ${player.playingAs} at ${indexes.join(',')}`)
}

printForPlayer(game().player1, game().board);
printForPlayer(game().player2, game().board);

this is a bit complex, but it works without loop

CodePudding user response:

One way is to loop over each row to create an array with all the places where the player has his own symbol.

Using reduce(), we can find all the indexes of the symobl of the current player, then after the loop, use join() to show it.

const data = {player1: {username: 'ABC', playingAs: 'X'}, player2: {username: 'XYZ', playingAs: '0'}, board: [['0', null, 'X'], ['X', '0', null], ['0', null, 'X'] ] };
const logPlayer = (player) => {
    const ox = data[player].playingAs;
    let indexes = [];
    
    for (let row in data.board) {
        const ii = data.board[row].reduce((prev, cur, i) => (cur === ox) ? [ ...prev, i ] : prev,[]);
        if (ii.length > 0) ii.map(i => indexes.push(`${ row   1}-${i   1}`));
    }
    console.log(`${player} has placed an '${ox}' on the following places (row-column)`, indexes.join(", "));
}

logPlayer('player1');
logPlayer('player2');

player1 has placed an 'X' on the following places (row-column) 1-3, 2-1, 3-3
player2 has placed an '0' on the following places (row-column) 1-1, 2-2, 3-1
  • Related