Eloquent Javascript第4章:数组到列表/ listToArray练习

时间:2015-03-01 23:15:55

标签: javascript arrays

Question from eloquentjavascript

  

编写一个函数arrayToList,用于构建类似于的数据结构   前一个给出[1,2,3]作为参数,并写一个listToArray   从列表生成数组的函数。还写了帮手   函数prepend,它接受一个元素和一个列表并创建一个新的   将元素添加到输入列表前面的列表,以及n,   它接受一个列表和一个数字,并返回给定的元素   在列表中的位置,或在没有这样的元素时未定义。

任何人都可以不用任何行话解释这个答案吗? 我只能通过指示学习。

以下是我为arrayToList提出的建议: 因此,开始列表为null,创建循环递减,并在内部定义“i”,然后返回列表。

function arrayToList(array){ //pass list as parameter
    var list = null; // don't know why we make it null
    for (var i=array.length-1; i>=0; i--)  // why -1 on the length?
        list = {value: array[i], rest:list}; //clueless
    return list;
}

rest:list对象中的list是什么?

6 个答案:

答案 0 :(得分:2)

@eloquent的最后评论需要修改:

var arr1 = [10, 20, 30];

function arrayToList(arr) {
  var list = {};

 for (var i = 0; i < arr.length; i++) {
    list.value = arr.splice(0, 1)[0];
    list.rest = (arr.length > 0) ? arrayToList(arr) : null;
 }

 return list;
}

console.clear();
console.log(  arrayToList(arr1) );

答案 1 :(得分:1)

编辑:为什么要投票?我回答他的问题,虽然他们是模糊不清的。

  

我们不知道为什么我们将其变为空

可能只是要明确初始值为null(与undefined相对应)。无论如何都不需要分配null

  

为什么长度为-1?

因为length是从1开始的(带有4个项的数组的长度为4),但是索引到数组是0-base(array [0]返回第1项)。

  

无能

此步骤正在创建嵌套列表对象。第一个循环创建一个列表,其值在该数组位置,第二个循环创建一个包装列表,其中包含该位置的值和指向上一个列表的指针,依此类推。

答案 2 :(得分:1)

  

rest:list对象中的list是什么?

它在对象文字中创建属性rest,并在将该对象分配给变量list之前为其分配变量list的值。请注意,这发生在一个循环中,所以它的作用是获取旧值并用引用旧值的新值覆盖它。

正是您需要构建嵌套列表结构。

  

var list = null; // don't know why we make it null

这是初始值,它将放在列表的“结尾”。如果数组为空,则返回它,如果数组有一个元素,它将成为返回的对象的rest属性。如果数组有多个元素......

  

为什么长度为-1?

因为数组是零索引的,即它们的索引从0length-1。当我们向后迭代时,我们需要这个奇怪的初始值和i >= 0比较。

答案 3 :(得分:0)

function arrayToList(arr) {
  var obj = {};
  for(var i = 0 ; i < arr.length; i++) {
    if(i == arr.length) {
     return obj.rest = null;
    }
    obj.value = arr.splice(0,1);
    obj.rest = arrayToList(arr);
  }
  return obj;
};

console.clear();
console.dir(arrayToList([1,2,3,4,5]));

答案 4 :(得分:0)

作为免责声明,我想说我自己是一个新手,我在这里学习事物并可能通过这样做来帮助他人。这就是我理解第二个问题已经解决的方式。

  

还要编写一个listToArray函数,该函数从列表中生成一个数组。

以下代码将起作用:

function listToArray(list) {
    let arr = [];
    for(; list !== null; list = list.rest) {
      arr.push(list.value);
    }
    return arr;
}

list参数将仅包含将要插入的参数。在我们的例子中是:{value: 10, rest: {value: 20, rest: null}

请记住,雄辩的Javascript中的代码将使用包含3个元素[10, 20, 30]的数组创建列表,但是在此示例中,我们仅使用由2个元素组成的列表。

在执行时,代码将执行以下操作:

第一次(第一次循环):

  1. 省略for循环的初始化(不要定义任何变量或 做任何事情)
  2. 检查列表是否不为空-否,因为此时此刻 列表等于{value: 10, rest: {value: 20, rest: null}
  3. 使列表(函数的参数)等于list.rest
    • 请记住,.rest只是对象列表的一个属性,它指向另一个对象-在我们的例子中它将指向{value: 20, rest: null}

第二次(第二循环):

  1. 省略for循环的初始化(不要定义任何变量或 做任何事情)

  2. 检查列表是否不为空-不,因为在     此刻列表等于{value: 20, rest: null}

  3. 再次使list等于list.rest-但此时它将 指向rest: null,因此这次列表的值将是 rest键的值,即null

第三次(第三循环):

  1. 省略
  2. 检查列表是否不为空-在这种情况下,请停止 执行并转到return语句
  3. 返回arr

我的答案基于:https://gist.github.com/laichejl/32d98af04caa66bd195f#file-exercise-js-L18

答案 5 :(得分:0)

我的递归解决方案:

function arrayToList([...arr], n = 0){
  return (n < arr.length) ? {value: arr[n], rest: arrayToList(arr, n + 1)} : null;
} 

function listToArray({...list}, arr = []){
  arr.push(list.value);
  return (list.rest != null) ? listToArray(list.rest, arr) : arr;
}

console.log(arrayToList([10, 20]));
// → {value: 10, rest: {value: 20, rest: null}}

console.log(listToArray(arrayToList([10, 20, 30])));
// → [10, 20, 30]