簡體   English   中英

按 object 屬性值過濾數組

[英]Filter array by object property values

我正在編寫一個 function 來處理 javascript 數組過濾。 我知道要過濾的值,所以我知道如何以一種相當簡單的方式進行過濾,但我希望代碼更具可擴展性。

我寫了這樣一個function:

 const items = [
{
    prop1: 'Jotahan',
    prop2: 'London',
    prop3: '1234567'
},
{
    prop1: 'Jones',
    prop2: 'Paris',
    prop3: '987'
}
];

const filters = { prop2: 'Paris', prop3: '987' };

   const handleFilters = (items, filters) => {
        return items.filter((item) => {
            if (filters.prop3 && filters.prop2) {
                return item.prop3 === filters.prop3 && item.prop2 === filters.prop2;
            }

            if (filters.prop3) {
                return item.prop3 === filters.prop3;
            }

            if (filters.prop2) {
                return item.prop2 === filters.prop2;
            }
        });
    }

我對此並不完全滿意。 我認為它可以寫得更好。 如果出現第三個參數,我不想將它添加到 if - 它應該是自動的。

我在 stackoverflow 上搜索了幾個主題,查看了 lodash 文檔以尋找一些好的解決方案,但我不知道我能用這個做些什么。

如果我理解正確,您只想保留與所有過濾器匹配的項目:

 const items = [ { prop1: 'Jotahan', prop2: 'London', prop3: '1234567' }, { prop1: 'Jones', prop2: 'Paris', prop3: '987' } ]; const filters = {prop2: 'Paris', prop3: '987'}; const handleFilters = (items, filters) => { return items.filter((item) => Object.entries(filters).every(([key, val]) => item[key] === val) ) }; console.log(handleFilters(items, filters))

這基本上檢查過濾器的每個 (key, val) 是否存在於項目中

private handleFilters (items, ...props) {
    return items.filter(item => props.every(prop => item[prop] === prop));
}

要動態使用過濾器 object,您可以考慮使用類似Object.keys()的東西。

這是您的示例代碼更改為使用它:

const items = [
    {
        prop1: 'Jotahan',
        prop2: 'London',
        prop3: '1234567'
    },
    {
        prop1: 'Jones',
        prop2: 'Paris',
        prop3: '987'
    }
];

const filters = { prop2: 'Paris', prop3: '987' };

const handleFilters = (items, filters) => {
    return items.filter(item => {
        return Object.keys(filters).some(filterKey => item[filterKey] === filters[filterKey])
    });
}

它循環遍歷項目,就像你已經做的一樣。 但是,現在它還循環通過filters object 中設置的鍵。 some() function 返回 boolean; 如果回調為true ,則為false ;如果回調為 false,則為 false。 在這里它檢查item[filterKey]中的值是否與filters[filterKey]中的值相同。

請務必注意,如果任何過濾器值與項目的屬性匹配,這將返回項目。 如果所有值都必須在過濾的項目中,您將需要使用Object.keys(filters).every(filterKey => item[filterKey] === filters[filterKey]) every function 僅在所有 filterKeys 與item中檢查的鍵具有相同值時才返回 true。

也可以使用Object.entries() ,它允許直接使用該值,但在此示例中,為了保持一致性,我選擇僅使用鍵。

您可以使用for..in刪除多個 if 塊

 const items = [ { prop1: 'Jotahan', prop2: 'London', prop3: '1234567' }, { prop1: 'Jones', prop2: 'Paris', prop3: '987' } ]; const filters = { prop2: 'Paris', prop3: '987' }; const handleFilters = (items, filters) => { return items.filter((item) => { for(const key in filters) { if (filters[key];== item[key]) { return false; } } return true; }). } console,log(handleFilters(items, filters))

它與您的代碼所做的相同。

您可以使用Object.key進行過濾,並以精確的方式過濾各種方法。

const items = [
      {
        prop1: 'Jotahan',
        prop2: 'London',
        prop3: '1234567'
      },
      {
        prop1: 'Jones',
        prop2: 'Paris',
        prop3: '987'
      }
    ];
    
    const filters = { prop2: 'Paris', prop3: '987' };
    
    const handleFilter = (items, filters) => {
      return items.filter((item) => Object.keys(filters).every((key) => item[key] === filters[key]));
    }
    
    console.log(handleFilter(items, filters))

Some Improvement over @David Alvarez approach, here i have used Object.keys instead of Object.entries as Object.key is faster than Object.entries here is the comparison: https://www.measurethat.net/Benchmarks/Show/3685 /0/objectentries-vs-objectkeys-vs-objectkeys-with-extra-ar

 const items = [ { prop1: 'Jotahan', prop2: 'London', prop3: '1234567' }, { prop1: 'Jones', prop2: 'Paris', prop3: '987' } ]; const filters = {prop2: 'Paris', prop3: '987'}; const handleFilters = (items, filters) => ( items.filter((item) => Object.keys(filters).every(key => item[key] === filters[key]) ) ); console.log(handleFilters(items, filters))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM