1

I have a 2D array in a React project defined in state/the constructor that looks like this:

constructor(props){
    super(props);

    this.state = {
      boardHeight: 50,
      boardWidth: 30,
      iterations: 10,
      reset: false,
      alive: false,
      board: [],
      randomNum: ''
    };

    this.state.board = new Array(this.state.boardHeight).fill(new Array(this.state.boardWidth).fill(0));
  }

Later on in my program I want to fill the 2D array with a random number between 0 and 1. If I use the .map function I can put a random number into the array like this:

  componentDidMount = () => {
    const data = this.state.board;

    // Generates Array of random numbers
    const startingBoard = data.map(Math.random)

    console.log('Starting board contains ' + startingBoard);

    // After startingBoard is working I can set state with startingBoard
    this.setState({
       board: startingBoard
    });
  }

const startingBoard = data.map(Math.random) successfully puts random numbers into one dimension of the 2D array. How can I nest a second .map function so that I can create random numbers for both dimensions of this array?

I am using this array for a game board grid. I need to generate random numbers for any square in the grid (i.e. [0][0], [0][1], etc...), so I need to be able to create random numbers for both arrays within this 2D array.

Something like this:

 const starting - data.map((x, index) => {
                      x.map((y, index) => {
                        return Math.random;
                      })
    }) 
Nick Kinlen
  • 1,356
  • 4
  • 30
  • 58

1 Answers1

1

.fill(new Array(this.state.boardWidth).fill(0)) fills all rows with the same array instance, so changes in one row would change all rows. map can be used after fill to make separate arrays :

board = Array(this.state.boardHeight).fill().map(_ => 
          Array(this.state.boardWidth).fill().map(_ => Math.random() ) );  
Slai
  • 22,144
  • 5
  • 45
  • 53
  • might as well turn that into a self-calling function? `const mapRandom = e => e.forEach ? e.map(mapRandom) : Math.random();` and then call it as `arr.fill().map(mapRandom)`? – Mike 'Pomax' Kamermans Sep 23 '18 at 02:32
  • @Mike'Pomax'Kamermans not sure I follow .. seems like more overhead and complexity than op might be ready for. As a side note, any reason for using `e.forEach ?` instead of `e.map ?` for checking if e is array? – Slai Sep 23 '18 at 02:48
  • This worked and thanks for pointing out the issue with the 2D array. One more question: how would I round the numbers up/down using Math.floor? .map won't allow me to chain it. – Nick Kinlen Sep 23 '18 at 03:01
  • @NickKinlen I guess something like `=> Math.floor(Math.random() * n)` https://stackoverflow.com/questions/1527803/generating-random-whole-numbers-in-javascript-in-a-specific-range, but seems like the answer to your previous question already shows how to generate random 0 or 1 – Slai Sep 23 '18 at 03:05
  • 1
    not really, I tend to go with foreach mostly because it's obvious the code's testing for an array bup map would work just fine. As for overhead: none, and complexity also none, but it does mean this now works for _any_ dimensional array. Not just "2 dimensional". – Mike 'Pomax' Kamermans Sep 23 '18 at 16:12