JavaScript, объясняющий поведение функции с 2 циклами для создания многомерного массива

#javascript #arrays #loops #for-loop #multidimensional-array

Вопрос:

Я написал функцию ниже с ожидаемым и фактическим возвратом. Я действительно ценю, если кто-то может помочь объяснить поведение/логику.

Редактировать: Я добавил пример, чтобы показать, почему я в замешательстве. Я хотел понять, почему после 2-го цикла первый элемент outerArray был изменен, когда я ввел значение в 1-й цикл.

 function makeArray(n, val) {
 let outerArray = [];
 let innerArray = [];

 for (let i = 0; i < n; i  ) {
  for (let y = 0; y < n; y  ) {
   innerArray.push(val);
  }
  outerArray.push(innerArray);
  console.log(outerArray[0]);
  console.log(outerArray[i]);
 }
  return outerArray;
}

console.log(makeArray(2,"x"));
// 1st outer loop -> outerArray[0] = outerArray[i = 0] = ["x", "x"]
// 2nd outer loop -> outerArray[0] = outerArray[i = 1] = ["x", "x", "x", "x"]
// Result -> [[x,x,x,x],[x,x,x,x]]
// Expected -> [[x,x],[x,x,x,x]]
 

Комментарии:

1. ваши ожидания неверны. [[x,x],[x,x,x,x]] можете ли вы объяснить, почему вы ожидаете такого результата

2. Вам нужно немного лучше объяснить свой алгоритм. зачем makeArray(2,"x") производить [[x,x],[x,x,x,x]] ? Это кажется совершенно произвольным.

3. Javascript-это синхронный язык (Википедия); каждая отдельная строка кода начинается в одно и то же время и заканчивается сама по себе. Результат вашего кода может технически изменяться при каждом его запуске (в зависимости от аппаратного и программного обеспечения). Ваш код будет работать на асинхронном языке, таком как Python.

4. Я ожидаю, что после первого внешнего цикла [x,x] будет перенесен во внешний массив, и он останется таким. Мои извинения, если это кажется произвольным или бессмысленным, но я просто хотел лучше понять основы javascript.

5. Привет, Рохо, я новичок, поэтому я еще не понимаю концепцию синхронного и асинхронного. Если вы не возражаете, не могли бы вы подробнее рассказать?

Ответ №1:

  1. Вам нужен счетчик для второго цикла
  2. Для цикла отлично работает, если вы используете
  3. Вам нужно увеличить или скопировать счетчик в первый цикл
     function makeArray(n, val) {
      let outerArray = [];
      let innerArray = [];
      let _n = n; // 1

      for (let i = 0; i <= n - 1; i  ) { // 2
        innerArray = [];
        for (let y = 0; y <= _n - 1; y  ) { // 2
          innerArray.push(val);
        }
        outerArray.push(innerArray);
        _n = _n * 2; // 3
      }
      return outerArray;
    }
    
    const arr = makeArray(2, "x");
    
    console.log(arr); 

Комментарии:

1. Привет, спасибо, что нашли время помочь мне. Я хотел бы спросить, можете ли вы объяснить подробнее: 1. почему переназначить _n 2. в чем заключается фундаментальное изменение, которое вы вносите.

2. _n — динамическая длина внутреннего массива. на первой итерации _n=2 это приводит к [‘x’,’x’]. когда _n будет перепроектирован * 2, он вступит в силу на следующей итерации. Во второй итерации _n=4 это приводит к [‘x’,’x’, ‘x’,’x’]. Затем вы можете адаптировать его к своему варианту использования.

Ответ №2:

Цикл Javascript ведет себя как любой другой цикл языка. Ошибка заключалась в том, что вы вставляли один и тот же внутренний массив внутрь внешних массивов, в то время как они смотрят на » n » внутренних массивов, они указывают на один и тот же внутренний массив.

  function makeArray(n, val) {
     let outerArray = [];
     let innerArray = [];
    
    // lets run from 1 for simplicity if n is 2 it will run twice
     for (let i = 1; i <= n; i  ) {
      innerArray = [] // first we create new array every time
    //  for (let y = 0; y < n; y  ) {  you are always running the inner look n tiles 
    for (let y = 1; y <= n * i; y  ) { // where as you expect it to run i * n times eg 2 * 1, 2 * 2 etc
       innerArray.push(val);
      }
      outerArray.push(innerArray); // we are pushing new inner arrary every time due to innerArray = []
      console.log('innerArray', innerArray,'i: ', i); 
     }
     
      return outerArray;
    }

  console.log('restult: ',makeArray(2,"x")); 

Комментарии:

1. Привет, спасибо, что уделили мне время. Чтобы не повторяться, поэтому я сошлюсь на свой комментарий выше. Я ожидаю, что после первого внешнего цикла [x,x] будет перенесен во внешний массив, и он останется таким. Мои извинения, если это кажется произвольным или бессмысленным, но я просто хотел лучше понять основы javascript.

2. Можете ли вы сказать нам, чего вы ожидаете, когда ввод будет выполнен(3,»X»)

3. Еще раз привет. Я ожидаю,что это будет [[x,x, x], [x,x,x,x,x, x],[x,x,x,x,x,x,x,x]]. Просто так работает логика в моей голове, она не должна быть правильной или что-то в этом роде.

4. Я добавил пример, чтобы лучше показать свое замешательство. Еще раз спасибо вам за потраченное время.