1

I'm creating a dungeon crawler game using React.js and I was initializing the board using Array.fill(0). but when I set an element inside the 2d array it sets the entire Array (column) to 'player' instead of a singular element. I have another createBoard() function, commented out, that works correctly. So why does this happen and how can I use Array.fill correctly?

Here is my Board component:

import React, {Component} from 'react';
import Cell from './Cell';

class Board extends Component {
  constructor(props) {
    super(props);
    const dim = 10;
    let board = this.createBoard(dim, dim);
    this.state = {
      board: board,
    };
  }

  createBoard = (row, col) => {
    return Array(row).fill(Array(col).fill(0));
  }

  // createBoard = (rows, cols) => {
  //   let board = [];
  //   for (let i = 0; i < rows; i++) {
  //     let row = [];
  //     for (let j = 0; j < cols; j++) {
  //       row.push(0);
  //     }
  //     board.push(row);
  //   }
  //   console.log(board);
  //   return board;
  // }

  movePlayer = () => {

  }

  componentDidMount() {
    this.setPiece(this.props.player);
  }

  setPiece = (loc) => {
    let brd = this.state.board;
    const row = loc[0];
    const col = loc[1];
    console.log('row: '+row+' col: '+col+' ==='+brd[row][col]);
    brd[row][col] = 'player';
    console.log('setPiece: ',brd);
    this.setState({board: brd});
  }

  renderCell = (cell) => {
    switch(cell) {
      case 0:
        return 'floor';
      case 1:
        return 'wall';
      case 'player':
        return 'player';
      default:
        return 'floor';
    }
  }

  render() {
    return (
      <div className='board'>
      {this.state.board.map((row, i) => {
        return row.map((cell, j) => {
          return (
            <Cell
              key={[i, j]}
              loc={[i, j]}
              type={this.renderCell(cell)}
            />
          );
        })
      })}
      </div>
    );
  }
}

export default Board;
1
  • Because your first fill is simply filling every column position with references to the same array. Commented Jun 25, 2017 at 19:09

2 Answers 2

3

You are using Array#fill correctly. Array#fill populates the array cells with the same value:

  1. The sub array is created - Array(col).fill(0)
  2. All row arrays are filled with the array reference - Array(row).fill(Array(col).fill(0))

To prevent that, you can use other methods of array creation, that create instead of clone the value. For example Array#from:

const row = 10;
const col = 5;
const result = Array.from({ length: row }, () => new Array(col).fill(0));

result[0][2] = 5

console.log(result);

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

Comments

1

You can fill 2D array with a help of Array.fill in a such way:

let arr = Array(5).fill(0).map(x => Array(5).fill(0))

2 Comments

This one looks great! It makes perfect sense to me!
This doesn’t answer the question what the difference between the working and the non-working approach is and why the non-working one isn’t working. The issue is that .fill(new Array()) will fill an array with the same array reference.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.