javascript-基于多个键值对搜索对象数组的优化方法

我编写了一个通用扩展方法,该方法将返回与所有给定搜索条件(lookUpArray)匹配的项目.这是Demo.

/***************************Extension Method****************************/

    var utils = {};
            // Could create a utility function to do this
            utils.searchInArray = function (lookUpArray, caseSensitiveSearch) {
                if (!lookUpArray || lookUpArray.length <= 0)
                    return null;

                caseSensitiveSearch = caseSensitiveSearch || false;
                var self = this;
                var item = null;
                for (var index = 0; index < self.length; index++) {
                    item = self[index];
                    var exist = true;
                    for (var i = 0; i < lookUpArray.length; i++) {
                        if (item[lookUpArray[i].key] === lookUpArray[i].value) {
                            exist = exist * true;
                        } else { exist = exist * false; }
                    }
                    if (exist)
                        return item;
                };
                return exist ? item : null;
            };

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



/***************************Extension Method****************************/


        var inputObjectArray= [
            { emailType: 'primary', id: 1, username: 'saurabh', email: 'test@gmail.com', phone: '123' },
            { emailType: 'additional', id: 2, email: 'test2@gmail.com' },
            { emailType: 'additional', id: 2, email: 'test2@gmail.com', username:'spp' }
        ];

        //Below is the search criterion array. Extension method should return only that object which 
        //matches complete below lookUpArray
        var lookUpArray = [{ key: 'emailType', value: 'additional' }, { key: 'id', value: 2 }];

        var result = inputObjectArray.excSearchObjArrayForKeyValue(lookUpArray);
        console.log(result);

是否有可能优化(性能)以上搜索?

解决方法:

这取决于您的用例.如果您将相当频繁地运行搜索功能(与修改数组的频率相比),并且如果搜索的键数有限,那么可能值得创建和维护类似索引的结构.现在,您的查找是一个O(m * n)操作,其中m是键的数量,n是数组中的项的数量.有了适当的数据结构,查找可能会变为O(m)操作.由于我猜想n可能是到目前为止更大的数字,因此这可以使搜索范围更加有效.

如果这样做没有意义,那么至少应该使内部回路短路.

            var self = this;
            for (var index = 0; index < self.length; index++) {
                var item = self[index];
                var matches = true;
                for (var i = 0; i < lookUpArray.length; i++) {
                    var lookUpItem = lookUpArray[i];
                    if (item[lookUpItem.key] !== lookUpItem.value) {
                        matches = false;
                        break;
                    }
                }
                if(matches) {
                    return item;
                }
            };
            return null;

或者,如nnnnnn所建议的,您可以使用标签更简洁地完成相同的操作:

            var self = this;
            outer:
            for (var index = 0; index < self.length; index++) {
                var item = self[index];
                for (var i = 0; i < lookUpArray.length; i++) {
                    var lookUpItem = lookUpArray[i];
                    if (item[lookUpItem.key] !== lookUpItem.value) {
                        continue outer;
                    }
                }
                return item;
            };
            return null;

如果您使用的是ES6,则甚至可以利用.find()和.every()函数.

            var self = this;
            return self.find(item => 
                lookUpArray.every(lookUpItem => 
                    item[lookUpItem.key] === lookUpItem.val));

我建议不要将此方法添加到Array原型中.我只是将其设为实用程序方法.

上一篇:C#是否具有零成本抽象?


下一篇:python-此代码效率太低,如何增加内存和执行效率?