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

时间:2021-04-30 18:18:55

标签: javascript arrays

对于这个问题 我已经得到了我自己想要的答案但是 我的解决方案很长并且有多个循环。

所以我在这里问是因为我想要一个替代解决方案。

我想要的是 我想通过 3 个属性过滤数组。条件是如果用户填写属性函数需要搜索该属性。如果用户将属性留空,我们可以跳过过滤该属性

这是我的示例数据

type ActualKeys = keyof typeof shortcuts['save' | 'open']
type PermittedKeys = keyof DesiredShape
// does not work because ActualKeys does not include `thisShouldError`
assertNever(null as unknown as Exclude<ActualKeys,PermittedKeys>)

这里是搜索功能

我想要的是如果用户不给搜索属性我想返回原始数组,如果用户不填写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", }, ]; 我想搜索匹配solutionToSearch & {的对象{1}},

同时如果用户不填写industryToSearch而留空 我想搜索对象。与 integrationToSearchindustryToSearch 属性相匹配,所有 3 个值的 ViceVersa

solutionToSearch

如您所见,我多次循环并生成了许多不必要的变量。 我想改进我的代码,有人可以帮忙吗。

4 个答案:

答案 0 :(得分:2)

查看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);

您可以通过传递参数而不是依赖外部作用域的变量来进一步改进这一点。此外,您可以按属性名称进行过滤,而不是创建一个新变量来为每个属性名称定义搜索参数。

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);

答案 1 :(得分:2)

您可以将具有与属性相同的键的对象作为要比较的对象。

此解决方案无需搜索即可使用 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; }

答案 2 :(得分:-1)

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);

答案 3 :(得分:-1)

我真的很喜欢 Nina 的通用和可扩展的方法,但她可能对目标对象中的“缺失属性”有点过于宽容。也许通过省略 !o[k] || 代码会产生 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; }