开发者

fastest way to get a subset of a collection in javascript

I have a master collection of items with unique ID's. At some point I have a subset of IDs from the master list that belong to some sub grouping if you will. The subset is just a reference of IDs of items that exist in the master list. Is there a way I can ask the master list for just the items that match the IDs in my subset without having to loop through the entire master collection? Just trying to find the fastest way to do this rather than the standard loop.

   //go through master list and determine which items belong to this sub item grouping
    for (var item = 0; item < masterListItems.开发者_StackOverflow中文版length; ++item ) {
      for (var subItem = 0; subItem < subItems.length; ++subItem ) {
         if (masterListItems[item].Id == subItems[subItem].Id) { //if it is a sub item
           //do some UI specific thing
         }
      }
    } 


Here is a solution with jQuery.grep. Filtering in 3 lines :

var master = [{ Id: 3 },{ Id: 1 },{ Id: 2 }]
var ids = [{ Id: 1 },{ Id: 3 }];

$(document).ready(function()
{
// Filtering with 3 lines
    idList = [];
    $.each(ids,function(index,value) { idList[idList.length] = value.Id; });
    elems = $.grep(master,function(element){ return idList.indexOf(element.Id) > -1; });

    $.each(elems,function(index,value){
        alert(value.Id);
    });
});

Edit: Be careful, on Internet Explorer, you will have to define indexOf yourself, as this example :

if(!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(needle) {
        for(var i = 0; i < this.length; i++) {
            if(this[i] === needle) {
                return i;
            }
        }
        return -1;
    };
}


You can run over the master list once to create "mapping" of the "Id" then one loop over the subset items:

var masterListMapping = new Array();
for (var i = 0; i < masterListItems.length; i++)
    masterListMapping[masterListItems[i].Id] = true;
for (var subItem = 0; subItem < subItems.length; subItem++) {
    if (masterListMapping[subItems[subItem].Id] == true) { //if it is a sub item
           //do some UI specific thing
    }
}


//example item is an object, ID is string
var item = { ID: "exampleID112233",
            data: 4545 }; //sample item

var masterList = {}; //masterList as a dictionary

//for each item created, use its ID as its key.
masterList["exampleID112233"] = item;

var subCat1 = []; //sublist is an array of ID;
subCat1.push("exampleID112233");

//you can also make new sublists as array, push the item's ID in them.
var subCat2 = ["anotherID334455"];

//iterate through sublist
for (var i = 0; i < subCat1.length; i++) {
  //access the referenced item
  masterList[subCat1[i]].data += 4;
}

//DELETING: remove the ID from all sublists, then delete it from masterlist.


Why do you want to hardcode referencing when you have language constructs for that?

If you have unique id for items why don't you make them a hash effectively?

// effective {hash}
var masterListItems  = { 
  uid_1: { /* item definition */ },
  uid_2: { /* item definition */ },
  uid_3: { /* item definition */ },
  // ...
};

Then the subset of items can be represented in 3 ways:

// another hash
var subItems = {
    uid_6:   masterListItems["uid_6"],   // effective referencing of the
    uid_321: masterListItems["uid_321"], // masterList items
    // ...
};
// or array of items
var subItems = [
    masterListItems["uid_6"],
    masterListItems["uid_321"],
    // ...
];
// or array of ids
var subItems = [
    "uid_6]",
    "uid_321",
    // ...
];

The tradeoffs:

  • hashes are good for uniquely indexed and effective for lots of get/set operations
  • arrays are good for numerically indexed data, or when the most common usage is iteration
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜