我有一個物件陣列。我需要撰寫一個函式,該函式將通過作為引數物件傳遞的屬性/值來搜索陣列。例如,我有這個用戶陣列:
const items = [{
firstName:"John",
lastName: 'Doe',
password: '*******',
email: '[email protected]',
role: 'ROLE_ADMIN'
},
{
firstName:"Jane",
lastName: 'Doe',
password: '********',
email: '[email protected]',
role: 'ROLE_USER'
},
{
firstName:"John",
lastName: 'Roe',
password: '**********',
email: '[email protected]',
role: 'ROLE_USER'
}]
鑒于我將以下引數傳遞給函式
{firstName: 'John'}
我應該為兩個名為 John 的用戶回傳一個包含 2 個物件的陣列。如果我通過這個引數:
{firstName: 'John', role: 'ROLE_ADMIN'}
那么我應該回傳一個只有 1 個用戶(在這種情況下)與兩個引數匹配的陣列。
如果沒有找到匹配的用戶 - 回傳一個空陣列。如果 params 是一個空物件 - 回傳整個陣列。
所以我寫了這個函式:
findMany(params) {
return new Promise((resolve, reject) => {
const keys = Object.keys(params)
if (!keys.length || !this.items.length) return resolve(this.items)
let result = []
let isMatch = false
for (const item of this.items) {
for (const key of keys) {
if(item[key] === params[key]) {
isMatch = true
} else {
isMatch = false
}
if (!isMatch) break
}
if (isMatch) result.push(item.toJSON())
}
resolve(result)
})
}
雖然它作業得很好而且我確實得到了想要的結果,但我想知道有沒有更優雅的方式來寫這個?嵌套回圈讓我有點惱火,這將時間復雜度增加到 O(n2)。那么有沒有更優雅的解決方案呢?
而且我仍然不在乎有人可能傳遞不存在的屬性的情況,即
{firstName: 'John', role: 'ROLE_ADMIN', someProperty: 'some value'}
不知道如何解決它...
uj5u.com熱心網友回復:
可能的解決方案的實施非常簡單。基本上必須撰寫一個filter函式。
這樣的函式接收單個專案,并根據一些比較邏輯回傳任一布林值。
此外,可以利用該filter方法的第二個thisArg引數,該引數將保存要匹配的鍵值對,作為物件參考提供。
因此,只需要遍歷提供的物件entries,并且必須回傳every查找的鍵值對是否在當前處理的 中具有匹配的對應物件item。
function doesItemMatchEveryBoundEntry(item) {
return Object
// `this` refers to the bound and to matched entries.
.entries(this)
.every(([key, value]) => item[key] === value);
}
const items = [{
firstName: 'John',
lastName: 'Doe',
password: '*******',
email: '[email protected]',
role: 'ROLE_ADMIN',
}, {
firstName: 'Jane',
lastName: 'Doe',
password: '********',
email: '[email protected]',
role: 'ROLE_USER',
}, {
firstName: 'John',
lastName: 'Roe',
password: '**********',
email: '[email protected]',
role: 'ROLE_USER',
}];
console.log(
"{ firstName: 'John' } ...",
items
.filter(
doesItemMatchEveryBoundEntry,
{ firstName: 'John' },
),
);
console.log(
"{ firstName: 'John', role: 'ROLE_ADMIN' } ...",
items
.filter(
doesItemMatchEveryBoundEntry,
{ firstName: 'John', role: 'ROLE_ADMIN' },
),
);
// OP ... If no matching users found - return an empty array.
console.log(
"{ firstName: 'John', role: '' } ...",
items
.filter(
doesItemMatchEveryBoundEntry,
{ firstName: 'John', role: '' },
),
);
// OP ... If params is an empty object - return the entire array.
console.log(
"{ /* empty */ } ...",
items
.filter(
doesItemMatchEveryBoundEntry,
{ /* empty */ },
),
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
uj5u.com熱心網友回復:
您可以使用過濾器過濾掉陣列。
const items = [
{
firstName: "John",
lastName: "Doe",
password: "*******",
email: "[email protected]",
role: "ROLE_ADMIN"
},
{
firstName: "Jane",
lastName: "Doe",
password: "********",
email: "[email protected]",
role: "ROLE_USER"
},
{
firstName: "John",
lastName: "Roe",
password: "**********",
email: "[email protected]",
role: "ROLE_USER"
}
];
function match(params) {
const keys = Object.keys(params);
return items.filter((item) => {
let flag = true;
keys.every((key) => {
if ((item[key] && item[key] !== params[key]) || !item[key]) {
flag = false;
return false;
}
return true;
});
return flag;
});
}
console.log(match({ firstName: "John",role: "ROLE_USER" }));
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/491303.html
標籤:javascript 数组 目的
上一篇:從后端回圈串列
