React — заполнение 2D-массива случайными числами с использованием .map и .fill

У меня есть 2D-массив в проекте React, определенный в состоянии/конструкторе, который выглядит так:

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));
  }

Позже в моей программе я хочу заполнить 2D-массив случайным числом от 0 до 1. Если я использую функцию .map, я могу поместить случайное число в массив следующим образом:

  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) успешно помещает случайные числа в одно измерение двумерного массива. Как я могу вложить вторую функцию .map, чтобы я мог создавать случайные числа для обоих измерений этого массива?

Я использую этот массив для сетки игрового поля. Мне нужно генерировать случайные числа для любого квадрата в сетке (т.е. [0][0], [0][1] и т. д.), поэтому мне нужно иметь возможность создавать случайные числа для обоих массивов в этом 2D множество.

Что-то вроде этого:

 const starting - data.map((x, index) => {
                      x.map((y, index) => {
                        return Math.random;
                      })
    }) 

person Nick Kinlen    schedule 23.09.2018    source источник


Ответы (1)


.fill(new Array(this.state.boardWidth).fill(0)) заполняет все строки одним и тем же экземпляром массива, поэтому изменения в одной строке изменят все строки. map можно использовать после fill для создания отдельных массивов:

board = Array(this.state.boardHeight).fill().map(_ => 
          Array(this.state.boardWidth).fill().map(_ => Math.random() ) );  
person Slai    schedule 23.09.2018
comment
может также превратить это в функцию самовызова? const mapRandom = e => e.forEach ? e.map(mapRandom) : Math.random();, а затем назвать его как arr.fill().map(mapRandom)? - person Mike 'Pomax' Kamermans; 23.09.2018
comment
@Mike'Pomax'Kamermans не уверен, что я понимаю ... кажется, что больше накладных расходов и сложности, чем может быть готов оператор. В качестве примечания, есть ли причина использовать e.forEach ? вместо e.map ? для проверки, является ли e массивом? - person Slai; 23.09.2018
comment
Это сработало, и спасибо за указание на проблему с 2D-массивом. Еще один вопрос: как мне округлить числа вверх/вниз, используя Math.floor? .map не позволит мне связать его. - person Nick Kinlen; 23.09.2018
comment
@NickKinlen Я думаю, что-то вроде => Math.floor(Math.random() * n) stackoverflow.com/questions/1527803/, но похоже, что ответ на ваш предыдущий вопрос уже показывает, как генерировать случайные 0 или 1 - person Slai; 23.09.2018
comment
не совсем, я склонен использовать foreach в основном потому, что очевидно, что тестирование кода для карты массива bup будет работать очень хорошо. Что касается накладных расходов: нет, и сложности тоже нет, но это означает, что теперь это работает для любого размерного массива. Не только двухмерный. - person Mike 'Pomax' Kamermans; 23.09.2018