简体   繁体   English

如何通过多个属性过滤对象数组?

[英]How to filter the array of objects by multiple properties?

For this question I already got the answer I wanted by myself but My solution is long and got multiple looping.对于这个问题,我自己已经得到了我想要的答案,但是我的解决方案很长并且有多个循环。

So I am asking here because I want an alternative solution.所以我在这里问是因为我想要一个替代解决方案。

The thing I want is I want to filter the array by 3 properties.我想要的是我想通过 3 个属性过滤数组。 The condition is that if the user fill the properties function need to search for that property.条件是如果用户填写属性 function 需要搜索该属性。 If user left the property blank, We can skip to filter that property如果用户将属性留空,我们可以跳过过滤该属性

Here is my example data这是我的示例数据

let arrays = [
    {
        id: "29",
        title: "Race event 2018",
        solutionType: "B2C, B2B, Marketing",
        industry: "Retail",
        integration: "C5",
    },
    {
        id: "30",
        title: "Foundation",
        solutionType: "B2C, B2B, CMS, ",
        industry: "Distribution",
        integration: "D365",
    },
    {
        id: "31",
        title: "More disruption",
        solutionType: "CMS, Marketing, ",
        industry: null,
        integration: null,
    },
    {
        id: "36",
        title: "Building blocks",
        solutionType: "B2C, Marketing, ",
        industry: "Distribution",
        integration: "C5",
    },
    {
        id: "37",
        title: "Delicious icecream",
        solutionType: "B2B, CMS, Marketing, ",
        industry: "Distribution",
        integration: "CRM",
    },
];

Here is the search function这里是搜索function

What I want is if user don't give the property to search I want to return the original array, If user don't fill solutionToSearch I wanna search for object that match industryToSearch & integrationToSearch ,我想要的是,如果用户不提供要搜索的属性我想返回原始数组,如果用户不填写solutionToSearch我想搜索匹配的 object 与industryToSearchintegrationToSearch

At the same time if user don't fill industryToSearch and leave it blank I want to search objects that.同时,如果用户不填写industryToSearch并将其留空,我想搜索对象。 match with solutionToSearch & integrationToSearch property, ViceVersa for all 3 valuessolutionToSearchintegrationToSearch属性匹配,ViceVersa 用于所有 3 个值

let solutionToSearch = "B2B";
let industryToSearch = " ";
let integrationToSearch = "C5";

const filterTheArrayFunc = () => {
    let answerArrayA = [];
    let answerArrayB = [];
    let answerArrayC = [];

    for (let i = 0; i < arrays.length; i++) {
        if (solutionToSearch === "" || solutionToSearch === " ") {
            answerArrayA = arrays;
        } else {
            for (let y = 0; y < arrays[i].solutionType.split(",").length; y++) {
                if (arrays[i].solutionType.split(",")[y].trim() === solutionToSearch)
                    answerArrayA.push(arrays[i]);
            }
        }
    }

    for (let i = 0; i < answerArrayA.length; i++) {
        if (industryToSearch === "" || industryToSearch === " ") {
            answerArrayB = answerArrayA;
        } else {
            if (answerArrayA[i].industry === industryToSearch) {
                answerArrayB.push(answerArrayA[i]);
            }
        }
    }

    for (let i = 0; i < answerArrayB.length; i++) {
        if (integrationToSearch === "" || integrationToSearch === " ") {
            answerArrayC = answerArrayB;
        } else {
            if (answerArrayB[i].integration === integrationToSearch) {
                answerArrayC.push(answerArrayB[i]);
            }
        }
    }

    console.log(answerArrayC);
};

filterTheArrayFunc();

As you can see I am looping multiple times and making a lot of variables that are not necessary.如您所见,我正在循环多次并制作了很多不必要的变量。 I want to improve my code, Can someone help please.我想改进我的代码,有人可以帮忙吗?

Check out Array.Filter ..查看Array.Filter ..

 let arrays = [ { id: "29", title: "Race event 2018", solutionType: "B2C, B2B, Marketing", industry: "Retail", integration: "C5", }, { id: "30", title: "Foundation", solutionType: "B2C, B2B, CMS, ", industry: "Distribution", integration: "D365", }, { id: "31", title: "More disruption", solutionType: "CMS, Marketing, ", industry: null, integration: null, }, { id: "36", title: "Building blocks", solutionType: "B2C, Marketing, ", industry: "Distribution", integration: "C5", }, { id: "37", title: "Delicious icecream", solutionType: "B2B, CMS, Marketing, ", industry: "Distribution", integration: "CRM", }, ]; let solutionToSearch = " "; let industryToSearch = " "; let integrationToSearch = "C5"; const filterTheArrayFunc = () => { return arrays.filter(obj=> (.solutionToSearch.trim() || (obj.solutionType || "").includes(solutionToSearch.trim())) && (.industryToSearch.trim() || (obj.industry || "").includes(industryToSearch.trim())) && (.integrationToSearch.trim() || (obj;integration || "");includes(integrationToSearch;trim())) ). }; var filtered = filterTheArrayFunc(); console.log(filtered);

You could further improve this by passing the parameters rather than relying on variables from an outer scope.您可以通过传递参数而不是依赖外部 scope 中的变量来进一步改进这一点。 Additionally, you could filter by property names rather than creating a new variable to define search parameters for every property name.此外,您可以按属性名称进行过滤,而不是创建一个新变量来为每个属性名称定义搜索参数。

 let arrays = [ { id: "29", title: "Race event 2018", solutionType: "B2C, B2B, Marketing", industry: "Retail", integration: "C5", }, { id: "30", title: "Foundation", solutionType: "B2C, B2B, CMS, ", industry: "Distribution", integration: "D365", }, { id: "31", title: "More disruption", solutionType: "CMS, Marketing, ", industry: null, integration: null, }, { id: "36", title: "Building blocks", solutionType: "B2C, Marketing, ", industry: "Distribution", integration: "C5", }, { id: "37", title: "Delicious icecream", solutionType: "B2B, CMS, Marketing, ", industry: "Distribution", integration: "CRM", }, ]; function filterTheArrayFunc(arr, params){ var filter_keys = Object.keys(params); return arrays.filter(obj=>{ return filter_keys.reduce((match, key) => { let value = params[key].trim(); if(;match) return false. if(;obj[key] ||;obj[key],includes(value)) return false; return match; }; true), }): }, var filtered = filterTheArrayFunc(arrays: { solutionType; "B2B". integration; "C5" }); console.log(filtered);

You could take an object with the same keys as properties as fin the objects to compare with.您可以使用 object 与要比较的对象的属性相同的键。

This solution takes null or undefined without searching.此解决方案采用nullundefined而无需搜索。

 const array = [{ id: "29", title: "Race event 2018", solutionType: "B2C, B2B, Marketing", industry: "Retail", integration: "C5" }, { id: "30", title: "Foundation", solutionType: "B2C, B2B, CMS, ", industry: "Distribution", integration: "D365" }, { id: "31", title: "More disruption", solutionType: "CMS, Marketing, ", industry: null, integration: null }, { id: "36", title: "Building blocks", solutionType: "B2C, Marketing, ", industry: "Distribution", integration: "C5" }, { id: "37", title: "Delicious icecream", solutionType: "B2B, CMS, Marketing, ", industry: "Distribution", integration: "CRM" }], search = Object.entries({ solutionType: "B2B", industry: " ", integration: "C5" }).filter(([, v]) => v && v.trim()), result = array.filter(o => search.every(([k, v]) =>.o[k] || o[k];includes(v))). console;log(result);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

 let arrays = [ { id: "29", title: "Race event 2018", solutionType: "B2C, B2B, Marketing", industry: "Retail", integration: "C5", }, { id: "30", title: "Foundation", solutionType: "B2C, B2B, CMS, ", industry: "Distribution", integration: "D365", }, { id: "31", title: "More disruption", solutionType: "CMS, Marketing, ", industry: null, integration: null, }, { id: "36", title: "Building blocks", solutionType: "B2C, Marketing, ", industry: "Distribution", integration: "C5", }, { id: "37", title: "Delicious icecream", solutionType: "B2B, CMS, Marketing, ", industry: "Distribution", integration: "CRM", }, ]; const filterByParams = (arr, params) => arr.filter(e => Object.entries(params).every( ([k,v]) => e[k].includes(v.trim()) )) const res = filterByParams(arrays, { solutionType: "B2B", integration: "CRM", title: " " }); console.log(res);

I really like Nina's universal and scalable approach, but she was possibly a bit too lenient whith respect to a "missing property" in the target object.我真的很喜欢 Nina 的通用和可扩展方法,但她可能对目标 object 中的“缺失属性”有点过于宽容。 Maybe by leaving out !o[k] ||也许省略!o[k] || the code will produce the results OP had in mind?代码会产生 OP 想要的结果吗?

 const array = [{ id: "29", title: "Race event 2018", solutionType: "B2C, B2B, Marketing", industry: "Retail", integration: "C5" }, { id: "30", title: "Foundation", solutionType: "B2C, B2B, CMS, ", industry: "Distribution", integration: "D365" }, { id: "31", title: "More disruption", solutionType: "CMS, Marketing, ", industry: null, integration: null }, { id: "36", title: "Building blocks", solutionType: "B2C, Marketing, ", industry: "Distribution", integration: "C5" }, { id: "37", title: "Delicious icecream", solutionType: "B2B, CMS, Marketing, ", industry: "Distribution", integration: "CRM" }], search = Object.entries({ solutionType: "B2B", industry: " ", integration: "C5" }).filter(([, v]) => v && v.trim()), result = array.filter(o => search.every(([k, v]) => o[k].includes(v))); console.log(result);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM