【问题标题】:Going from an list to an array从列表到数组
【发布时间】:2016-10-19 14:19:47
【问题描述】:

所以我正在解决一个问题,我成功解决了第一部分,这让我可以像这里一样向对象添加一些类型

function arrayToList(array) {
  var list = null;
  for (var i = array.length - 1; i >= 0; i--)
    list = {value: array[i], rest: list};
  return list;
}

现在这一切都很好,但现在我正在尝试同时创建另一个功能,它会做相反的事情。解决办法在这里

function listToArray(list) {
  var array = [];
  for (var node = list; node; node = node.rest)
    array.push(node.value);
  return array;
}

有人可以解释一下这个 for 循环是如何工作的吗?我不明白这个 for 循环的结构,我在 w3 学校中寻找了一个类似的例子。为什么for循环的第二个参数是变量?还有为什么第三个参数把我们的变量等同于一个类型?

【问题讨论】:

  • 注意for循环的定义如下:for (declaration; condition; modification)所以在第二个例子中,node是循环继续的条件。只要定义了node,它就会继续。而修改只是将节点设置为下一项,node.rest。

标签: javascript arrays linked-list


【解决方案1】:

说明

For loops contain 3 statements in their body:

for (initialization; condition; final-expression)

我想您了解initializationfinal-expression 的工作原理,但condition 是确定for 循环是继续迭代还是终止的测试。

由于node 在这种情况下可以是对象或null,因此它们是“真实”和“虚假”值。 Boolean(null) === false,所以如果当前迭代已经到达null,它就知道链表已经结束,可以停止循环了。

演练

好的,所以第二个for循环以node = list开头的原因是因为list是一个需要遍历的object。请注意,下一个node 始终包含在node.rest 中。因此,为了“增加”,我们需要使用node = node.restnode.rest 分配给node。现在我们了解了这些部分:

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

剩下的部分是检查 for 循环是否应该继续或终止的语句。我们知道如果nodenull,那么就没有更多的节点可以遍历了,所以我们可以检查一下。在 JavaScript 中,由于Boolean(null) === false,我们可以简单地断言node 是“真实的”以继续,因为Boolean({}) === true。所以node这个语句只是检查是否继续:

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

演示

在学习语言结构时,最有用的事情之一就是运行代码并亲自查看输出的样子。在此示例中,array

["hello", "world", "how", "are", "you", "today"]

list

{"value": "hello", "rest": {"value": "world", "rest": {"value": "how", "rest": {"value": "are", "rest": {"value": "you", "rest": {"value": "today", "rest": null}}}}}}

/* ignore this */
console.log = function (data) {
  if (typeof data === 'object') {
    data = JSON.stringify(data, null, 2);
  }
  
  document.write('<pre>' + data + '</pre>');
}

/* pay attention to everything below here */
function arrayToList(array) {
  console.log('arrayToList\n\n');

  var list = null;
  for (var i = array.length - 1; i >= 0; i--) {
    list = {value: array[i], rest: list};
    console.log('index: ' + i);
    console.log('value: ' + JSON.stringify(array[i]));
    console.log(list);
    console.log('-----');
  }
  
  return list;
}

function listToArray(list) {
  console.log('listToArray\n\n');

  var array = [];
  for (var node = list; node; node = node.rest) {
    array.push(node.value);
    console.log('index: ' + (array.length - 1));
    console.log('value: ' + JSON.stringify(array.slice(-1)[0]));
    console.log(node);
    console.log('-----');
  }

  return array;
}

var array = ['hello', 'world', 'how', 'are', 'you', 'today'];

var list = arrayToList(array);

listToArray(list);
pre {
  margin: 0;
  padding: 0;
}

【讨论】:

  • 好的,我知道 for 循环现在是如何工作的了。但逻辑仍然让我感到困惑。 var node = list 初始化到底是什么意思?通常我们说 i = 0 作为初始化,给变量一个起始值。那么为什么我们的起始值是“列表”呢?
  • 您能否逐步解释每次迭代会发生什么?
  • 好的,我想我现在明白了,所以当我们在节点中时,它被初始化为列表。设置节点等于 node.rest,只要我们在节点中。如果我们在节点中,则将该节点的值放入一个数组中。但是我仍然不确定设置 node = node.rest 的目的是什么。
  • 哇。惊人的演练解释。非常感谢..这是一些很深的东西。
  • 没有看解决方案就自己完成了。谢谢!!
【解决方案2】:

在 for 的第一条语句中,您将节点变量分配给列表。这是在第一次迭代运行时它将保持的初始值。那么第二条语句是一个条件,如果为真/不为空,则继续执行for循环。您正在将节点变量重新分配给 node.rest 的第三个语句,这将使第二个语句更改为下一个循环。当节点变量为空值时,循环将退出。

【讨论】:

  • 谢谢。我现在了解 for 循环的实际语法,但对我为什么这样做感到困惑。为什么我将节点设置为列表?为什么我要设置 node = node.rest?为什么我每次迭代都在数组中插入 node.value?
猜你喜欢
  • 2011-12-19
  • 2014-07-04
  • 1970-01-01
  • 2013-03-15
  • 2013-03-01
  • 2019-11-17
  • 1970-01-01
  • 1970-01-01
  • 2022-01-08
相关资源
最近更新 更多