对象中的数组返回长度为0,即使存在元素

时间:2011-06-14 20:50:30

标签: javascript arrays trie

我正在尝试在Javascript中实现一个Trie,这很容易,但我似乎已经用我的对象遇到了障碍。

节点的结构如下:

var node = {
    children: []
}

Children是一个由字符串中的字母映射的节点数组。所以字符串“Test”看起来像这样:

root = {
  children: [
      't' => {
          children: [
              'e' => {
                   children: [
                       's' => {
                            children: [
                                 't' => {
                                      children: []
                                  }
                            ]
                        }
                   ]
               }
          ]
      }
  ]
};

因此每个children数组的长度应为1,但如果执行类似alert(this._root.children.length);的操作,则会得到零。有关为何发生这种情况的任何想法?

以下是我实施的其余部分:

function Trie() {
    this._root = {
        children: []
    };
}

Trie.prototype = {

    //restore constructor
    constructor: Trie,

    add: function (str){
        var curr = this._root,
            prev,
            currchar;
        // For each character in the string
        for(var i = 0, j = str.length; i < j; i++) {
            // Insert only lowercase letters for efficiency
            currchar = str.toLowerCase().charAt(i);
            prev = curr;
            curr = prev.children[currchar];
            // Traverse until we hit a non-existant node
            if(typeof(curr) == "undefined") {
                // Make a new node
                prev.children[currchar] = {
                    children: []
                };
                curr = prev.children[currchar];
            }
        }
    }

3 个答案:

答案 0 :(得分:2)

您正在向数组实例对象添加属性,而不是向数组添加元素。 length属性仅包含数组元素,而不包括数组实例对象上的属性。

var a = [23, 42];
console.log(a.length); // 2
a['foo'] = 'bar';
console.log(a.length); // 2
a[2] = 1337;
console.log(a.length); // 3

<强>编辑: 您可以改为构造节点,如下所示:

var node = {
    children: {},
    length: function () {
        var i = 0;
        var k;

        for (k in this.children) {
            if (this.children.hasOwnProperty(k)) {
                i++;
            }
        }
        return i;
    }
};

当然这是低效的。您应该在其原型上使用length方法定义一个Node类。或者,定义更新length属性的add方法。

答案 1 :(得分:2)

我认为问题在于您使用javasrcipt数组作为关联数组(在其他语言中可以找到)。在javascript中,“associative”数组是没有length属性的对象。普通数组有数字索引。

与问题无关,但您可能会发现this有用。

答案 2 :(得分:-1)

也许你想要

str.toLowerCase().charCodeAt(i)

而不是

str.toLowerCase().charAt(i)

如果str"f1",则您要添加到子数组的属性为"f""1",这会导致数组中包含名为{{1}的属性}和长度0,以及另一个长度为f且属性为2的子数组。

要仅获取数字属性,应确保属性名称是有效的数组索引 - 正整数可用31位表示。

使用1代替charCodeAt,您将获得属性名称charCode102,而不是49"f"。< / p>