![](/img/trans.png)
[英]How can you map an array to a new array based on the key-value pairs in an object?
[英]Optimized way to search an object array based on multiple key-value pairs
我寫了一個通用擴展方法,它將返回一個匹配所有給定搜索條件(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原型中。 我只是把它變成一種實用方法。
您可以使用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);
您可以使用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
如果有幫助,請標記正確。
要獲得第一個匹配的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;
});
});
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.