Для цикла с объектом - PullRequest
       1

Для цикла с объектом

0 голосов
/ 11 февраля 2019

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

Может кто-нибудь объяснить мне, как возможна итерация циклас объектом?

let list = {
   value: 1,
   rest: {
      value: 2,
      rest: {
         value: 3,
         rest: null
    }
  }
};

ниже приведена функция, выполняющая работу

function listToArray(list) {
  let arrays = [];
  for (let node = list; node; node = node.rest) { // big question: how it works or possible?
    arrays.push(node.value);
  }
  return arrays;
}
console.log(listToArray(list)); // -> [1, 2, 3]

Ответы [ 6 ]

0 голосов
/ 11 февраля 2019

Как работают for петли:

Сначала вам нужно понять, как работают for петли.

Оператор for создает цикл, который состоит из трех необязательных выражений, заключенных в круглые скобки и разделенных точками с запятой, за которыми следует оператор (обычно оператор блока) для выполнения в цикле. MDN

Петля for имеет такую ​​структуру:

for ([initialization]; [condition]; [final-expression])
   statement

Выражения initialization, condition иfinal-expression может быть любым допустимым выражением.Любое или все эти выражения могут быть опущены (for(;;) является допустимым в javascript и создает бесконечный цикл).

Цикл for начинается с выполнения выражения initialization, если указано, затем повторяетследующие действия: проверьте, верен ли condition, если это так, то он выполняет statement (s) и final-expression по порядку, если condition ложно, он прекращает цикл.

ВотНапример, следующая диаграмма ( источник изображения ) :

for loop diagram

Соответствует следующему forцикл:

for(i = 2; i <= 6; i = i + 2)
  print i + 1

Обратите внимание, что initialization часть i = 2 выполняется только один раз, тогда как остальные (часть condition i <= 6, часть statement (s) и final-expression i = i + 2) может выполняться несколько раз (по порядку) в зависимости от condition.

Объяснение рассматриваемого кода:

for (let node = list; node; node = node.rest) { // big question: how it works or possible?
  arrays.push(node.value);
}

initialization часть этого цикла просто объявляет переменную node и устанавливает ее значение для корневого элемента list, эта часть выполняется только один раз, когда lОоп собирается начать.

Часть condition проверяет, является ли node (переменная) истинным или нет, в javascript объект является истинным, тогда как undefined - нет,это ложное значение (конечно, есть и другие истинные и ложные значения, но нас интересуют только эти два для этого конкретного примера).Концепция цикла заключается в том, чтобы перемещать объект от узла к узлу (см. final-expression часть ниже).Когда дочерний узел существует, следующим значением node будет этот узел (который является объектом), это означает, что это будет истинное значение, следовательно, условие будет истинным.Принимая во внимание, что если дочерний узел не существует, node будет undefined (ложное значение) и, следовательно, условие будет ложным.

final-expression просто устанавливает значение node вдочерний узел текущего узла, который является node.rest.Если он существует, node будет объектом, в противном случае это будет undefined.

0 голосов
/ 11 февраля 2019

цикл For состоит из трех частей

  1. инициализация - будет вызываться один раз (let node=list)
  2. условие продолжения - будет вызываться на каждой итерации (node)
  3. следующий шаг - будет вызван, когда 2 вернул true.Обычно вы хотите обновить переменную, созданную в 1

Давайте подробнее рассмотрим то, что на самом деле здесь происходит:

for(let node = list; node; node=node.rest)

Сначала высоздаем новую переменную с именем node со значением list
Далее, вы проверяете, нет ли у вас null или undefined.Эти два значения являются ложными, что означает, что оба возвращают false, когда они приводятся к логическому значению.Если это не так, ваш arrays.push будет выполнен, иначе ваш цикл будет прерван.
Наконец, вы обновляете node значением node.rest.Перед тем как ваш arrays.push будет выполнен с обновленным node, ваше состояние будет проверено снова.
Наконец, когда ваш node равен

{
   value: 3,
   rest: null
}

, ваша 3 часть цикла обновит переменную node, присвоив ей rest, то есть null и ваш 2 не пройдет, поэтому он будет прерван

0 голосов
/ 11 февраля 2019

for можно рассматривать как синтаксический сахар для while, даже если есть несколько различий низкого уровня, они одинаковы:

for (let i=0; i<10; i++) {
  console.log(i);
}

let i=0;
while(i<10) {
  console.log(i);
  i++;
}

Синтаксис for равен for(initialization, test, iteration).Это:

for (let node = list; node; node = node.rest) { doSomething(node); }

Возможно, легче понять, если написать так:

let node = list;
while(node) { // equivalent to: while(node!==null) {
  doSomething(node);
  node = node.rest;
}
0 голосов
/ 11 февраля 2019

Вы также можете сделать это рекурсивным, так как это облегчает объяснение.

Если ваш объект null, просто верните массив (как есть), иначе верните вызов следующему rest и добавьте value к массиву.

obj = { value: 1, rest: {...} }, arr = []          // Add 1 to arr and return obj.rest
obj = { value: 2, rest: {...} }, arr = [ 1 ]       // Add 2 to arr and return obj.rest
obj = { value: 3, rest: null  }, arr = [ 1, 2 ]    // Add 3 to arr and return null
obj = null,                      arr = [ 1, 2, 3 ] // Return arr [ 1, 2, 3 ]

let list = {
  value: 1,
  rest: {
    value: 2,
    rest: {
      value: 3,
      rest: null
    }
  }
};

function listToArray(obj, arr = []) {
  return obj == null ? arr : listToArray(obj.rest, arr.concat(obj.value));
}

console.log(listToArray(list)); // -> [1, 2, 3]
.as-console-wrapper { top: 0; max-height: 100% !important; }
0 голосов
/ 11 февраля 2019

Допустим, вы хотите получить доступ к вложенному объекту, содержащему value: 3.Затем вы должны сделать:

 list.rest.rest // { value: 3, rest: null }

Вы также можете записать это в несколько строк как:

 let node = list; // { value: 1, rest: { ... } }
 node = node.rest; // { value: 2, rest: { ... } }
 node = node.rest; // { value: 3, rest: null }

, и это можно обобщить для n повторений как

 for(let node = list; node; node = node.rest) {
   //...
 }

Пример из реального мира:

Вы живете в маленькой деревне, с севера на юг есть только одна улица.Рядом с улицей есть несколько домов.Вы живете в конце маленького городка, в северном конце.Вашего соседа зовут Боб.У Боба также есть соседка по имени Алиса.У Алисы есть сосед по имени Ева.Если вы хотите прогуляться по улице, вы можете навестить Боба, Алису и Еву.Или вы просто идете к следующему дому, пока не дойдете до конца маленького городка.

 const bob = you.southernNeighbour;
 const alice = bob.southernNeighbour;
 const eve = alice.southernNeighbour;

 // ...

let current = you; // you start where you are.
while(current) // as long as there is a house, walk 
  current = current.southernNeighbour; // go to the next southern neighbour
0 голосов
/ 11 февраля 2019

В качестве вступления обратите внимание, что цикл for имеет следующий синтаксис:

for (statement 1; statement 2; statement 3) {
    // code block to be executed
}
  1. Statement 1 выполняется (один раз) перед выполнениемблока кода.
  2. Statement 2 определяет условие для выполнения блока кода.
  3. Statement 3 выполняется (каждый раз)после выполнения блока кода.

Итак, на каждой итерации вы переходите на один уровень глубже от tree с node = node.rest.Цикл останавливается, потому что в конце концов вы попытаетесь получить доступ к свойству rest для некоторых node, у которых нет этого ключа или для которого установлено null, это будет оценено как undefined или null соответственно, и так как условие остановки цикла for заключается в проверке переменной node, она остановится, когда это undefined или null (обратите внимание, что это значения falsy в Javascript).

Пример с отладкой :

let list = {
   value: 1,
   rest: {
      value: 2,
      rest: {
         value: 3,
         rest: null
    }
  }
};

function listToArray(list)
{
    let arrays = [];
    
    for (let node = list; node; node = node.rest)
    {
        console.log("Current node is: " + JSON.stringify(node));
        console.log("Node value is: " + node.value);
        arrays.push(node.value);
        console.log("Next node will be: " + JSON.stringify(node.rest));
    }

    return arrays;
}

console.log(listToArray(list));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...