列出 JavaScript 中的数据结构

IT技术 javascript
2021-03-10 09:53:08

Eloquent JavaScript书中的一个练习中,我需要基于数组 [1, 2, 3] 创建一个列表数据结构(如下所示)。

教程JavaScript 数据结构 - 链接列表展示了如何做到这一点,但我并不真正理解教程中创建this.startthis.end变量的意图

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

我试图通过下面的代码解决这个问题。

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

这段代码给了我一个数组[0]的无限循环。我的代码有什么问题?

3个回答

教程展示了如何做到这一点,但我并不真正理解在教程中创建this.startthis.end变量的意图

本教程使用List带有一些辅助方法的递归结构包装器。它说:“每次需要访问列表末尾时,都可以通过遍历整个列表来避免记录end列表的末尾——但在大多数情况下,存储对列表末尾的引用更经济。

这段代码给了我一个数组[0]的无限循环。

不是真的,但它创建了一个带有线的循环引用list.rest = list;输出列表的代码可能会因此而窒息。

我的代码有什么问题?

您需要创建多个对象,在循环体内定义对象文字,而不是一遍又一遍地分配给同一个对象!此外,您应该array[i]在循环内部访问,而array[0]不仅仅是:

function arrayToList(array){
    var list = null;
    for (var i=array.length-1; i>=0; i--)
        list = {value: array[i], rest:list};
    return list;
}
我明白这段代码是如何工作的。但是你怎么想到向后而不是向前循环数组。在这种情况下,前向循环可以工作吗?
2021-05-15 09:53:08
前向循环可以工作,但需要那个奇怪的end“指针”(在这种情况下是一个变量)。最简单的方法是访问shift()数组中的第一个元素,并rest使用从数组尾部的递归调用来构建
2021-05-18 09:53:08

这种特殊的数据结构通常称为cons递归是处理 conses 的最自然(不一定是最有效)的方式。首先,让我们定义一些辅助函数(使用 LISP 表示法而不是“value/rest”):

function cons(car, cdr) { return [car, cdr] }
function car(a) { return a[0] }
function cdr(a) { return a[1] }

现在,要从数组构建 cons,请使用以下递归语句:

cons-from-array = cons [ first element, cons-from-array [ the rest ] ]

在 JavaScript 中:

function arrayToList(array) {
    if(!array.length)
        return null;
    return cons(array[0], arrayToList(array.slice(1)));
}

而反向函数同样是微不足道的:

function listToArray(list) {
    if(!list)
        return [];
    return [car(list)].concat(listToArray(cdr(list)));
}
疯狂,但有趣。很有道理。
2021-05-07 09:53:08
function arrayToList (arr) {
    var list = null;
    for (var i = arr.length - 1; i >= 0; i--) {
        list = {
            value: arr[i],
            rest: list
        };
    }
    return list;
}

function prepend (elem, list) {
    return {
        value: elem,
        rest: list
    };
}

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

function nth(list, num) {
  if (!list) {
    return undefined;
    } else if (num === 0) {
        return list.value;
    } else {
        return nth(list.rest, num - 1);
    }
}