0

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.

Aqdas
  • 868
  • 4
  • 16
  • 57
  • Please show us your attempt. – 0stone0 May 18 '22 at 14:29
  • `filter` does a loop internally, so you don’t save any loop using `filter`. – t.niese May 18 '22 at 14:29
  • You should use `filter` only if you really want to get an array that only includes specific elements of the original array. – t.niese May 18 '22 at 14:33
  • Also, You need to consider how You interpret results. Eg. `Player1 marked 'X' at 1,2,3` could mean that all three items are on first row, or first X is on second line, and two other on third line. – 83lynx May 18 '22 at 14:37
  • @83lynx, Board has three objects. and in each object, there is an array, right? so I want to find the position of X inside each array – Aqdas May 18 '22 at 14:40

3 Answers3

0

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

83lynx
  • 111
  • 5
0

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
0stone0
  • 34,288
  • 4
  • 39
  • 64
0

So here is my solution which worked for me.

First of all, null is always rendered as 0. So I hade to update my array as mentioned below

    board: 
        [
            ['✓', null, 'X'],
            ['X', '✓', null],
            ['✓', null, 'X']
        ] 

Secondly, after updating the board value in the array, the following solution worked for me.

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

let array = GameBoard.entries();
let tick = [];
let cross = [];
for (const [index,element] of array) {
    tick.push(element.indexOf(PlayerBMark)+ 1);
    cross.push(element.indexOf(PlayerAMark)+ 1);
}
 
console.log('Player ', PlayerA, ' Clicked ', PlayerAMark ,' at '+ cross);
console.log('Player ',PlayerB, ' Clicked ', PlayerBMark ,' at '+ tick);

Here is the result for this.

Player  ABC  Clicked  X  at 3,1,3
Player  XYZ  Clicked  ✓  at 1,2,1

Thanks everyone for all the help. But, still I am looking for How we can improve its performance and avoided looping?

Thanks again.

Aqdas
  • 868
  • 4
  • 16
  • 57