有没有比使用jQuery'更好的方法来搜索JavaScript数组;每个人都是谁?

有没有比使用jQuery'更好的方法来搜索JavaScript数组;每个人都是谁?,javascript,jquery,Javascript,Jquery,我经常需要搜索包含对象的javascript数组。我想在数组中搜索属性匹配的对象。例如,在Person对象数组中搜索Person的id/key==“ABC123” 使用jQuery使用$.each方法可以很容易地完成这项工作,这就是我所决定的。您可以在JSFIDLE中看到这个示例 我想知道是否有其他人找到了更快和/或更好的方法来做到这一点 var Person = function(code, name) { this.code = code; this.name = name;

我经常需要搜索包含对象的javascript数组。我想在数组中搜索属性匹配的对象。例如,在Person对象数组中搜索Person的id/key==“ABC123”

使用jQuery使用$.each方法可以很容易地完成这项工作,这就是我所决定的。您可以在JSFIDLE中看到这个示例

我想知道是否有其他人找到了更快和/或更好的方法来做到这一点

var Person = function(code, name) {
    this.code = code;
    this.name = name;
};
var people = [
    new Person("ABC123", "Tooth Fairy"),
    new Person("DEF456", "Santa Claus"),
    new Person("PIR000", "Jack Sparrow"),
    new Person("XYZ987", "Easter Bunny")
    ];

var utils = {};
// Could create a utility function to do this
utils.inArray = function(searchFor, property) {
    var retVal = -1;
    $.each(this, function(index, item) {
        if (item.hasOwnProperty(property)) {
            if (item[property].toLowerCase() === searchFor.toLowerCase()) {
                retVal = index;
                return false;
            }
        }
    });
    return retVal;
};

// or we could create a function on the Array prototype indirectly
Array.prototype.inArray = utils.inArray;

// let's use the prototype for now
var i = people.inArray("PIR000", "code");
$('#output').text(people[i].name);
有很多问题与此类似,但我还没有看到一个解决方案,而不是迭代(就像我在这里做的那样)

所以问题是。。。有更好的方法吗?

$。我想每个方法都是关于O(n)的。任何简单的“for”循环在找到一个适用的项时中断,最多为O(n),但平均而言,除非数组的后一项不断被发现是匹配的元素,否则该循环将更少。Array.filter是一种有效的方法,但不是某些浏览器的固有方法。如果您希望使用Array.filter方法,可以使用纯javascript实现。对于以本机方式承载它的浏览器,它可能会执行得更快,因为它们的实现可能是在本机代码中编译和运行的。但是filter方法在将数组中的元素“过滤”到新数组中时总是会产生O(n)

我个人坚持使用for(inti=0;…)方法。通过调用其他函数减少范围更改的开销,并且您可以轻松地“中断”匹配元素

我还想补充一点,您可以使用HTML5提供的本地数据库存储(使用SqlLite)。这显然没有得到广泛的支持,但如果有足够大的数据集,它将比任何其他javascript方法都快得多。如果您想查看,请访问以下链接:

这里有一种有点离谱的方法:从理论上讲,您可以为数据编制索引,并使用这些索引快速检索数据。您不需要将数据存储在javascript数组中,而是将其存储在DOM中,并使用诸如“data-id-5”之类的CSS类对元素进行“索引”。这使您能够在大多数主要浏览器中使用内置的本机选择器API。以下是一个例子:

DOM:


也许你可以用for..in循环。请参阅:。它的工作方式与php的foreach类似。

这本身并不能回答您的“搜索”问题,但它可能是您的解决方案。您可以创建一个专门的
PersonArray
类,对其中的人员进行索引。这种方法的性能是O(1),但它使用了更多的内存

var PersonArray = function(persons) {
    this.elements = {};
    var i;
    for (i=0; i < persons.length; i++) {
        this.elements[persons[i].code] = persons[i];
    }
};

PersonArray.prototype.fromCode = function(s) {
    return this.elements[s];   
};

var people = new PersonArray([
    new Person("ABC123", "Tooth Fairy"),
    new Person("DEF456", "Santa Claus"),
    new Person("PIR000", "Jack Sparrow"),
    new Person("XYZ987", "Easter Bunny")
    ]);

console.log(people.fromCode("ABC123"));  // Prints a person
console.log(people.fromCode("DEF456"));  // Prints a person
console.log(people.fromCode("NONE"));  // Undefined
var PersonArray=功能(人员){
this.elements={};
var i;
对于(i=0;i
您还可以将此方法扩展到索引其他字段


另请参见:and(100000个元素)。

通常,从数组中获取元素的速度不能快于O(n),除非您知道要索引的内容

例如,如果要对某个可比较的对象建立索引,则可以对数组排序并进行二进制搜索

如果在列上执行搜索,并且值是int或string,则可以使用普通Javascript对象作为哈希表

var people = [
    new Person("ABC123", "Tooth Fairy"),
    new Person("DEF456", "Santa Claus"),
    new Person("PIR000", "Jack Sparrow"),
    new Person("XYZ987", "Easter Bunny")
];

var people_table = {};
for(var i=0; i<people.length; i++){
    people_table[ people[i].id ] = people[i];
}

//fast search:
var someone = people_table['ABC123'];
var-people=[
新人(“ABC123”,“牙仙”),
新人(“DEF456”、“圣诞老人”),
新人(“PIR000”、“杰克·斯派洛”),
新人(“XYZ987”,“复活节兔子”)
];
var people_table={};

对于(var i=0;i如果您打算经常这样做,那么您可能希望为特定属性创建一个索引,以便可以更快地返回项。例如,下面实现了一个存储对象,该存储对象添加并获取添加到其中的对象

它保留了对象名的索引(如果它们有一个的话),因此获取它们是高效的

但是,您只会注意到大量对象(比如超过100个)和具有索引的对象(尽管您可以为任意数量的属性创建索引,并且可以使用更通用的方法)的性能提升

函数存储(){
this.store=[];
this.nameIndex={};
}
//将项添加到存储,如果具有name属性,则将name添加到name索引
Storage.prototype.addItem=功能(项){
var idx=this.nameIndex;
//如果项目具有name属性
if(item.hasOwnProperty('name')){
//如果已有具有该名称的项,请添加索引
//此项将添加到相同命名项的索引中
if(idx.hasOwnProperty(item.name)){
idx[item.name].push(this.store.length);
//否则,请将此项添加到索引中
}否则{
idx[item.name]=[this.store.length];
}
}  
//将项目添加到商店
此。存储。推送(项目);
}
//返回具有匹配名称的项的可能为空数组
Storage.prototype.getItemsByName=函数(名称){
var结果=[];
变量名称;
if(this.nameIndex.hasOwnProperty(name)){
list=this.nameIndex[name];

对于(var i=0,iLen=list.length;i如果我必须重复搜索一个数组,那么我迭代它一次,将每个键添加为一个对象的属性,然后在该对象中查找该键。这使所有查找的目标保持在O(n)+c、 存储是高效的,因为对象正在存储对数组数据的引用,或者它们是基元。简单而快速。

有一个类似的问题[here][1]。[1]:请参阅和@j08691这两个问题都在检查是否是精确的对象
var PersonArray = function(persons) {
    this.elements = {};
    var i;
    for (i=0; i < persons.length; i++) {
        this.elements[persons[i].code] = persons[i];
    }
};

PersonArray.prototype.fromCode = function(s) {
    return this.elements[s];   
};

var people = new PersonArray([
    new Person("ABC123", "Tooth Fairy"),
    new Person("DEF456", "Santa Claus"),
    new Person("PIR000", "Jack Sparrow"),
    new Person("XYZ987", "Easter Bunny")
    ]);

console.log(people.fromCode("ABC123"));  // Prints a person
console.log(people.fromCode("DEF456"));  // Prints a person
console.log(people.fromCode("NONE"));  // Undefined
var people = [
    new Person("ABC123", "Tooth Fairy"),
    new Person("DEF456", "Santa Claus"),
    new Person("PIR000", "Jack Sparrow"),
    new Person("XYZ987", "Easter Bunny")
];

var people_table = {};
for(var i=0; i<people.length; i++){
    people_table[ people[i].id ] = people[i];
}

//fast search:
var someone = people_table['ABC123'];
function Storage() {
  this.store = [];
  this.nameIndex = {};
}

// Add item to the store, if has name property, add name to name index
Storage.prototype.addItem = function(item) {
  var idx = this.nameIndex;

  // If the item has a name property
  if (item.hasOwnProperty('name')) {

    // If already have an item with that name, add index of
    // this item to indexs of same named items
    if (idx.hasOwnProperty(item.name)) {
      idx[item.name].push(this.store.length);

    // Otherwise, add this item to the index
    } else {
      idx[item.name] = [this.store.length];


    }
  }  
  // Add the item to the store
  this.store.push(item);
}

// Returns a possibly empty array of items with matching names
Storage.prototype.getItemsByName = function(name) {
  var result = [];
  var names;

  if (this.nameIndex.hasOwnProperty(name)) {
    list = this.nameIndex[name];

      for (var i=0, iLen=list.length; i<iLen; i++) {
        result.push(this.store[list[i]]);
      }
  }
  return result;
}

// Generic method for any property and value
Storage.prototype.getItemsByAttributeValue = function(propName, propValue) {
  // loop through items, return array of 
  // those with matching property and value
}


var store = new Storage();

store.addItem({name:'fred',age:'9'});

var obj = store.getItemsByName('fred');

alert(obj[0].age); // 9

store.addItem({name:'sally',age:'12'});

obj = store.getItemsByName('sally');

alert(obj[0].age); //12