javascript / jQuery:搜索和更新对象数组的最有效方法

时间:2014-09-07 14:56:51

标签: javascript jquery arrays json performance

我目前正致力于私人/乐趣项目,这是一款基于javascriptjQuery的小型浏览器游戏。

对于这个游戏我将数据保存到一个对象数组:

this.map.push(
    { 
        "id" : id, 
        "x" : pos_x,
        "y" : pos_y
    }
);

现在我需要经常查找和/或更新此阵列中的数据(在"实时")。

例如,当我需要在我的coords-system的某个位置找到array-index时,我正在使用jQuery' s $.each()函数:

this.getIndexAtPos = function(x, y)
{
    var index = false;
    $.each(this.map, function(key, obj){
        if(obj.x == x && obj.y == y)
        {
            index = key;
            return false;
        }
    });
    return index;
}


另一个例子:当我需要更新具有特定ID的对象的数据时,我正在使用jQuery' s $.map()函数:

this.updateCoordsById = function(id, x, y)
{
    this.map = $.map(this.map, function(obj, i)
    {
        if(obj.id == id)
        {
            //only update x, y!
            obj.x = x;
            obj.y = y;
            return obj;
        }
        else
        {
            return obj;
        }
    });
}
到目前为止,它对我来说都很好,但我在一台相当快的计算机上,随着游戏的扩展,将会有越来越多的这些行动。比如让我们说每秒钟进行几百次$.each$.map次呼叫 这就是为什么我担心性能问题,特别是在较慢的计算机上。


我的问题: 我知道$.each$.map在每次调用时(部分或全部)迭代我的数组。这就是为什么我在return false;函数中使用$.each的原因,只要找到条目就可以加快一些事情。

1。我可以通过使用其他jQuery功能或更改我使用它们的方式来提高性能吗? 2。有更好的方法(性能明智)通过使用原生javascript来解决这个问题吗?
3。我应该使用其他数据类型/结构来提升性能吗?

注意: 我需要实现的程序总是非常相似:通过coords(x,y)查找数组中的对象;通过id找到它们;通过坐标(x,y)更新对象;按ID更新对象,依此类推。


我将不胜感激任何帮助,意见和建议!

1 个答案:

答案 0 :(得分:1)

好的,因为这是一个网格,将它作为网格存储在内存中是有意义的。 二维数组将比一维数组更快地访问,并且还允许您通过坐标直接访问对象,而不是检查每个对象的坐标。

您还可以拥有一个容器对象,其中包含您的所有对象,其ID为属性,可让您快速按ID查找。

您可以通过在网格中存储对象的ID,然后通过ID在容器中查找对象来将它们放在一起。

我在http://jsfiddle.net/d75zkvnb/1/创建了一个小提琴,其中显示了一个简单的例子。 Map对象的结构如下:

var Map = {
    init: function(){
        this.Width = 10;
        this.Height = 10;

        // grid stores the coordinates and the IDs of the object at that coordinate
        // note this is stored by y then x.
        this.grid = [];
        // stored the actual objects, indexed by id
        this.objects = {};

        // set up the grid        
        for(var y = 0; y < this.Height; ++y)
        {
            this.grid.push(new Array(this.Width));
        }    
    },

    // gets the object at (x, y)
    GetAtCoord: function(x, y)
    {
        // find the id
        var id = this.grid[y][x];
        // directly access it from the array
        return this.objects[id];
    },

    // gets the object with the ID
    GetById: function(objId)
    {
        // direct access to the object
        return this.objects[objId];
    },

    // add an object at its stored coordinates
    AddObject: function(obj){
        this.grid[obj.y][obj.x] = obj.id;
        this.objects[obj.id] = obj;
    },

    // Move an object in the grid
    MoveObject: function(objId, newX, newY)
    {
        // get the objct to move
        var theObj = this.objects[objId];
        // reove it from the grid
        this.grid[theObj.y][theObj.x] = null;
        // updates its stored position
        theObj.x = newX;
        theObj.y = newY;

        // add it back to the grid
        this.grid[newY][newX] = objId;
    }
};