使用JavaScript将最新的数组索引存储在单独的数组中

我有一个对象的数组。 数组的键是使用.push()自动生成的。 有些对象可能会从数组中delete array[index]; 。 数组可能包含0到10K +条目中的任何内容。

这是声明和一些逻辑:

 var allClients = []; someFunction(client) { allClients.push(client); var callbackFunction = function() { var index = allClients.indexOf(client); try { delete allClients[index]; } catch (err) { console.error(err); } } } function getClientsMeetingCriteria(some_unique_id) { var filteredClients = allClients.filter(function(client) { return client.id_list.indexOf(some_unique_id) > -1; }); return filteredClients; } 

现在上面的代码(它是IRL的非常简化的版本)适用于100-300个客户端,但是对于500+的目的而言,它变得太慢了。 问题是getClientsMeetingCriteria()可能asynchronous每秒调用10次。 我需要设置与some_unique_idcaching作为关键。 我有caching代码,但我不知道如何将这些数据存储在其中..想象一下:

  1. client = {id:1, id_list='123;124;'}被添加到clients[]
  2. getClientsMeetingCriteria('123')返回[client {id:1...}]并caching响应
  3. delete client[0]被调用,客户端从clients[]被删除
  4. getClientsMeetingCriteria('123')被再次调用并返回caching的[client {id:1...}] ,但是该条目不再在clients[]

我知道在这种情况下JS传递值( return filteredClients )。 到目前为止,我想到了这一点:我可以实际循环访问getClientsMeetingCriteria()的数组,并查找匹配客户端的索引。 我把他们(索引)的数组放在caching下some_unique_id 。 我还保留一个数组索引与client_ids与数据是cachingsome_unique_id引用客户端ID的列表。 在调用delete allClients[index] ,我为index获取数组条目,从而得到应该刷新的caching键列表('some_unique_id')。 这似乎是一个普遍大的开销,但没有什么比每隔100毫秒循环1K对象…

你能想出更好的解决scheme吗? 有没有办法使链接对象的数组条目(索引),这将是最新的 – 换句话说,刷新(成为空)索引被删除时? 像迭代器一样。

PS我也意识到,我可以从caching中加载客户端ID的列表,并检查索引是否存在,但这并不能解决与添加一个匹配的“some_unique_id”的新客户端的问题。

一个数组是这个错误的数据结构。 使用一些对象,并设置索引,你根本不需要search。

我将假设每个客户的id属性是唯一的。 让我知道如果不是这样的话。

而且,我将采取getClientsMeetingCriteria() (下面的代码中的find方法getClientsMeetingCriteria()一个自由。 我将返回一个包含这些客户端的对象 ,而不是返回一个客户端数组 。 这主要是为了展示一个重要的观点:你实际上可以写这个代码,这样的检索是即时的。 整个function体很简单:

  return criteria[criterion] || {}; 

如果你需要一个很容易的数组(也将会非常快),所以我们将回到这个。

将此代码粘贴到您的Chrome或Firebug控制台并执行它:

 // Return a boolean telling if an object is empty (has no properties) function isEmpty( object ) { for( var name in object ) { return false; } return true; } // An object that keeps track of clients and criteria (id_list) function Clients() { // An object containing all of the clients that have been added // using clients.add(client). The client.id is the property name, // and the client object is the property value. So: // clients[clientID] is a client object with the given client.id var clients = {}; // An object containing every unique criterion ID. The criterion ID // is the property name, and the property value is an object // containing every client that has this criterion ID in its id_list // property. So: // criteria[criterionID] is an object containing clients // criteria[criterionID][clientID] is a client with that criterion var criteria = {}; // Internal function to split an id_list and iterate over it function eachCriterion( client, callback ) { var ids = client.id_list.split(';'); for( var i = 0, n = ids.length; i < n; ++i ) { callback( ids[i] ); } } // Add a client this.add = function( client ) { if( clients[client.id] ) { // already exists, return or error? } clients[client.id] = client; eachCriterion( client, function( id ) { if( ! criteria[id] ) { criteria[id] = {} } criteria[id][client.id] = client; }); }; // Remove a client this.remove = function( client ) { delete clients[client.id]; eachCriterion( client, function( id ) { delete criteria[id][client.id]; if( isEmpty(criteria[id]) ) { delete criteria[id]; } }); }; // Return an object containing all the clients that have the given // criterion in their id_list property this.find = function( criterion ) { return criteria[criterion] || {}; }; } var clients = new Clients; var client3 = { id:3, id_list:'10;20' }; var client1 = { id:1, id_list:'30;40;10' }; var client4 = { id:4, id_list:'40;20' }; var client5 = { id:5, id_list:'50;70' }; var client9 = { id:9, id_list:'10;70' }; var client2 = { id:2, id_list:'50;' }; var client7 = { id:7, id_list:'40;70;90' }; clients.add( client3 ); clients.add( client1 ); clients.add( client4 ); clients.add( client5 ); clients.add( client9 ); clients.add( client2 ); clients.add( client7 ); function find( id ) { console.log( 'Finding', id ); console.log( JSON.stringify( clients.find(id), null, 4 ) ); } find( '10' ); clients.remove( client3 ); find( '10' ); clients.remove( client1 ); find( '10' ); clients.remove( client9 ); find( '10' ); 

它会logging:

 Finding 10 { "1": { "id": 1, "id_list": "30;40;10" }, "3": { "id": 3, "id_list": "10;20" }, "9": { "id": 9, "id_list": "10;70" } } Finding 10 { "1": { "id": 1, "id_list": "30;40;10" }, "9": { "id": 9, "id_list": "10;70" } } Finding 10 { "9": { "id": 9, "id_list": "10;70" } } Finding 10 {} 

如果你真的需要一个数组来代替.find()返回的对象,你可以使用这个版本的find方法(或者任何类似的代码):

  this.find = function( criterion ) { var result = []; for( var id in criteria[criterion] ) { result.push( clients[id] ); } return result; };