代码之家  ›  专栏  ›  技术社区  ›  Rob

如何在JavaScript中迭代对象数组?

  •  1
  • Rob  · 技术社区  · 14 年前

    我使用PHP从数据库中获取“任务”,并将其编码为JSON。当我将数据传输到javascript时,我会得到如下结果:

    Array {
       [0] => Task {
          id: 2,
          name: 'Random Task',
          completed: 0
       }
       [1] => Task {
          id: 8,
          name: 'Another task',
          completed: 1
       }
    }
    

    等。

    6 回复  |  直到 14 年前
        1
  •  6
  •   Matthew Abbott    14 年前

    Javascript对象的特点是它们是必不可少的映射。您可以使用点符号(“object.property”)和索引符号(“object[“property”])访问属性。也可以使用for(i…)或for(in…)枚举其属性

    for (var i = 0; i < arrayObj.length; i++) { ... }
    
    for (var prop in arrayObj) { ... }
    

    我最近一直在做的是为array对象构建一些Linq风格的扩展:

    Array.prototype.Where = function(predicate) {
        Throw.IfArgumentNull(predicate, "predicate");
        Throw.IfNotAFunction(predicate, "predicate");
    
        var results = new Array();
        for (var i = 0; i < this.length; i++) {
            var item = this[i];
            if (predicate(item))
                results.push(item);
        }
    
        return results;
    };
    

    忽略我的自定义抛出类型,它基本上允许您执行以下操作:

    var item = arrayObj.Where(function(i) { return (i.id == 8); }).FirstOrDefault();
    

    如果你有兴趣的话,我会在某个时候把它全部公布出来?

        2
  •  2
  •   Brian Scott    14 年前

    通常,在Javascript中迭代数组集合的最有效方法是使用本机for循环。我之所以说“通常”是因为实现归结为每个浏览器的javascript实现,所以没有绝对确定的答案。

    http://solutoire.com/2007/02/02/efficient-looping-in-javascript/ 其中涵盖了每种主要迭代方法的性能,并从经验上得出了相同的结论。

        3
  •  2
  •   Anurag    14 年前

    如果您不需要维护顺序,那么最好的方法是创建一个常规对象,并按任务id进行索引 O(1) 进入。

    var tasks = {
       '2': {
          id: 2,
          name: 'Random Task',
          completed: 0
       },
       ...
    }
    

    如果您还需要维护顺序,那么可以编写一个OrderedMap“类”,通过创建任务id数组来维护顺序,但实际任务仍将存储在按任务id索引的对象中。因此基本上您需要:

    // internal API (to help maintain order)
    taskIDs = [a, b, c, ..];
    // internal API (for actual storage)
    tasks = {
        a: { .. },
        b: { .. },
    };
    
    // external API for iterating objects in order
    forEach(fn);
    // external API for accessing task by ID
    get(id);
    

    外部世界可能不知道您是如何维护顺序的,只要您提供一种很好的封装方式,按顺序迭代这些命令,并按任务id访问它们。

    source 对于 LinkedMap

        4
  •  2
  •   Rob    14 年前

    再多想一想,这就是我最后的结论:

    this.find = function (test) {
        var results = [];
        for (var i = 0,l = this.tasks.length; i < l; i++) {
            var t = this.tasks[i];
            if (eval(test)) {
                results.push(this.tasks[i]);
            }
        }
        return results;
    }
    

    这允许我做一个简单的tasks.find('t.id==2')或tasks.find('t.completed==1');

        5
  •  0
  •   Amarghosh    14 年前

    如果id是唯一的(并且大部分是连续的),您可以对数组进行一次重新排列,以便数组索引反映id。如果它们不是唯一的,您可以对它们进行排序并进行二进制搜索。

    但是只有经常从数组中按id访问项时,这才有用,否则排序的开销就不值了。

        6
  •  0
  •   Yngve Sneen Lindal    14 年前

    你的阵型大吗?如果不是,你可能不会赢得很多微秒优化它。

    只需使用一个普通的PHP关联数组,并通过json\u encode或您正在使用的任何东西来运行它。

    //Assume you have your original Array named $tasks:
    $dictionary = Array();
    foreach($tasks as $task)
        $dictionary[$task->getID()] = $task;