有没有办法将对象中的值映射到javascript中的数组索引?

mag*_*ekh 5 javascript arrays performance jquery knockout.js

预先确定解决方案只需要在最新版本的Chrome,Firefox和Safari中使用即可.

-

我试图使用关联数组用于具有knockout的大型数据集.我的第一次尝试使它成为一个真正的关联数组:

[1: {Object}, 3: {Object},...,n:{Object}]
Run Code Online (Sandbox Code Playgroud)

但淘汰赛并不满足于对此进行循环.所以我尝试了一种欺骗方式,希望:

[undefined, {Object}, undefined, {Object},...,{Object}]
Run Code Online (Sandbox Code Playgroud)

其中数组中的位置是数据库表中的PK ID.这个数组大约有3.2k个项目,并且每10秒左右迭代一次,因此需要速度.我尝试用拼接来做这件事,例如

$.each(data, function (index, item) {
    self.myArray.splice(item.PKID, 0, new Object(item));
}
Run Code Online (Sandbox Code Playgroud)

但是splice不会创建索引,所以因为我的第一个PKID是1,所以myArray[0]无论如何它仍然插入.如果我的第一个PK为500,它仍将从0开始.

我的第二个想法是初始化阵列,var myArray = new Array(maxSize)但这似乎很重要.我希望能够使用某种地图功能来做到这一点,但我不确定如何使键值转换为javascript中的索引值.

我的第三个想法是保留两个数组,一个用于轻松查找,另一个用于存储实际值.因此,它几乎通过在第一个示例中查找对象的索引并在第二个示例中使用该索引进行查找来组合前两个解决方案.这似乎是有多少人在淘汰赛中管理关联数组,但是由于数组大小以及它是一个具有不断增长的数据集的实时更新应用程序,这似乎是内存密集型的,并且在添加新信息时不易管理.

还有,也许我在这里打错了?我们通过淘汰将这些进入DOM,并使用名为isotope的库进行管理,正如我所提到的,它每10秒更新一次.这就是为什么我需要快速查找但是淘汰赛不想玩我的哈希表尝试.

- 清晰度编辑:所以在初始加载时,整个数组被加载(这是new Array(maxLength)将要去的地方,然后每10秒更新任何已更改的数据.这是我正在尝试快速更新的信息.

- 淘汰赛代码:

<!-- ko foreach: {data: myArray(), afterRender: setInitialTileColor } -->
    <div class="tile" data-bind="attr: {id: 'tileID' + $data.PKID()}">
        <div class="content">
        </div>
    </div>
<!-- /ko -->
Run Code Online (Sandbox Code Playgroud)

然后在更新上希望是:

$.each(data.Updated, function (index, item) {
    var obj = myModel.myArray()[item.PKID];
    //do updates here - need to check what kind of change, how long it's been since a change, etc
}
Run Code Online (Sandbox Code Playgroud)

小智 2

这是一个如何用正确的索引填充数组项的解决方案,因此它不会从第一个开始(我的意思是0(零))

只需在循环中使用

arr[obj.PKID] = obj;
Run Code Online (Sandbox Code Playgroud)

如果您的框架很聪明(使用 forEach 但不使用 for),它将从您的索引开始(例如下面的情况下的 500)

http://jsfiddle.net/0axo9Lgp/

var data = [], new_data = [];

// Generate sample array of objects with index field
for (var i = 500; i < 3700; i++) {
    data.push({
        PKID: i,
        value: '1'
    });
}

data.forEach(function(item) {
    new_data[item.PKID] = item;
});

console.log(new_data);
console.log(new_data.length); // 3700 but real length is 3200 other items are undefined
Run Code Online (Sandbox Code Playgroud)