我写了一个通用扩展方法,它将返回一个匹配所有给定搜索条件(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);
是否有可能在搜索之上优化(性能)?
答案 0 :(得分:2)
这取决于您的使用案例。如果您将经常运行搜索功能(与修改数组的频率相比),并且如果您可以搜索有限数量的可能键,则可能会发现创建和维护类似索引的结构是值得的。现在,您的查找是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原型中。我只是把它变成一种实用方法。
答案 1 :(得分:2)
您可以使用Array.prototype.filter
和Array.prototype.every
等数组函数,而不是自己迭代项目:
var utils = {
searchInArray: function(targetArray, lookupArray, caseSensitiveSearch) {
return targetArray.filter(function(x) {
return lookupArray.every(function(lookup) {
if (x[lookup.key] === undefined)
throw new Error('No ' + lookup.key + ' property in object ' + x);
if (typeof x[lookup.key] !== typeof lookup.value)
throw new Error('Type mismatch on property ' + lookup.key ' + in object ' + x);
if (typeof lookup.value === 'string' && caseSensitiveSearch)
return x[lookup.key].toLowerCase() === lookup.value.toLowerCase();
else
return x[lookup.key] === lookup.value;
});
});
}
};
工作演示片段:
var utils = {
searchInArray: function(targetArray, lookupArray, caseSensitiveSearch) {
return targetArray.filter(function(x) {
return lookupArray.every(function(lookup) {
if (x[lookup.key] === undefined)
throw new Error('No ' + lookup.key + ' property in object ' + x);
if (typeof x[lookup.key] !== typeof lookup.value)
throw new Error('Type mismatch on property ' + lookup.key ' + in object ' + x);
if (typeof lookup.value === 'string' && caseSensitiveSearch)
return x[lookup.key].toLowerCase() === lookup.value.toLowerCase();
else
return x[lookup.key] === lookup.value;
});
});
}
};
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' }
];
var lookUpArray = [{
key: 'emailType',
value: 'aDdItIoNaL'
}, {
key: 'id',
value: 2
}];
var result = utils.searchInArray(inputObjectArray, lookUpArray, true);
console.log(result);
&#13;
答案 2 :(得分:0)
您可以使用Arrays.find
功能。
find()方法返回数组中的值(如果是数组中的元素) 满足提供的测试功能。否则返回undefined。
看看这个例子:
var inventory = [
{name: 'apples', quantity: 2},
{name: 'bananas', quantity: 0},
{name: 'cherries', quantity: 5}
];
function findCherries(fruit) {
return fruit.name === 'cherries';
}
console.log(inventory.find(findCherries)); // { name: 'cherries', quantity: 5 }
您也可以编写自定义逻辑,例如。找到素数:
function isPrime(element, index, array) {
var start = 2;
while (start <= Math.sqrt(element)) {
if (element % start++ < 1) {
return false;
}
}
return element > 1;
}
console.log([4, 6, 8, 12].find(isPrime)); // undefined, not found
console.log([4, 5, 8, 12].find(isPrime)); // 5
如果有帮助,请标记正确。
答案 3 :(得分:0)
要获得第一个匹配的obj,您可以尝试这个
utils.searchInArray = function(lookUpArray, caseSensitiveSearch) {
if (!lookUpArray || lookUpArray.length <= 0)
return null;
caseSensitiveSearch = caseSensitiveSearch || true;
var self = this;
return self.find(function(obj) {
return lookUpArray.every(function(lookup) {
if (typeof lookup.value === 'string' && caseSensitiveSearch)
return obj[lookup.key].toLowerCase() === lookup.value.toLowerCase();
else
return obj[lookup.key] === lookup.value;
});
});
};
获取所有匹配的对象
utils.searchInArray = function(lookUpArray, caseSensitiveSearch) {
if (!lookUpArray || lookUpArray.length <= 0)
return null;
caseSensitiveSearch = caseSensitiveSearch || true;
var self = this;
return self.filter(function(obj) {
return lookUpArray.every(function(lookup) {
if (typeof lookup.value === 'string' && caseSensitiveSearch)
return obj[lookup.key].toLowerCase() === lookup.value.toLowerCase();
else
return obj[lookup.key] === lookup.value;
});
});
};