是否有更好的方法来搜索JavaScript数组而不是使用jQuery的每一个?

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

使用$ .each方法使用jQuery可以轻松完成,这正是我所解决的问题。 你可以在jsFiddle中看到这个例子。 http://jsfiddle.net/johnpapa/EJAFG/

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

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实现。 对于本地托管它的浏览器,它可能会执行得更快,因为它们的实现可能已编译并以本机代码运行。 但是过滤方法总是会产生O(n),因为它会将数组的元素“过滤”到新的数组中。

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

我还想补充一点,您可以使用由HTML 5提供的本地数据库存储(使用SqlLite)。这显然不被广泛支持,但是在给定足够大的数据集的情况下比其他任何javascript方法快得多。 如果您想查看,请点击此链接:

http://blog.darkcrimson.com/2010/05/local-databases/

这样做有点离谱你可以在理论上为你的数据建立索引并以快速的方式使用这些索引来检索它。 不是将数据存储在JavaScript数组中,而是将其存储在DOM中,并使用CSS类(如“data-id-5”)“索引”元素。 这为您提供了使用大多数主流浏览器内置的本机选择器API的优势。 这里是一个例子:

DOM:

 <div id="datastuff" style="display:none">
     <span class="data-id-ABC123" data-person='{"code": "ABC123", "name": "Tooth Fairy"}'></span>
     <span class="data-id-DEF456" data-person='{"code": "DEF456", "name": "Santa Claus"}'></span>
     <span class="data-id-PIR000" data-person='{"code": "PIR000", "name": "Jack Sparrow"}'></span>
     <span class="data-id-XYZ987" data-person='{"code": "XYZ987", "name": "Easter Bunny"}'></span>
 </div>

现在我们可以使用jQuery并查询它:我们将查询“ABC123”的关键字:

var person = $(".data-id-ABC123").data("person");
console.log(person.name);//Tooth Fairy

一般来说,除非你知道你想要索引的东西,否则你不能从数组中获得比O(n)更快的元素。

例如,如果索引可比的somethnig,则可以对数组进行排序并进行二分搜索。

如果您在列上进行搜索,并且值是整数或字符串,则可以使用纯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'];

在某一点之后,查询变得太复杂而无法用JavaScript轻松完成,因此发送处理服务器端可能是一个好主意,因此您可以使用更合适的工具,如关系数据库。


这本身并不能回答你的“搜索”问题,但它可能是你的一个解决方案。 您可以创建一个专门的PersonArray类,为其中的人员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

您也可以将此方法扩展到索引其他字段。

另请参阅:演示和基准(包含100,000个元素)。

链接地址: http://www.djcxy.com/p/74951.html

上一篇: Is there a Better Way to Search a JavaScript Array than Using jQuery's each?

下一篇: How to search for a string inside an array of strings