1

我有一个包含两个字段filter1filter2具有数组形式的值的对象

let filter = {filter1:["mine","your"]: filter2:["C","D"]} //值不固定

数据是对象数组的形式

let data = [
{ id:1, filter1:["mine"], filter2:["E","C"]},
{ id:2, filter1:["mine"], filter2:["E","C","F"]},
{ id:3, filter1:["your"], filter2:["C"]},
{ id:3, filter1:["your"], filter2:["D","C"]},
{ id:5, filter1:["other"], filter2:["F"]},
...
]

我必须过滤掉那些在特定键中存在任何一个字段的对象,例如,它filter是否{filter1:["mine"]: filter2:["F","D"]}会首先在数据对象的 filter1 中搜索 filter1 的任何元素,然后再搜索 filter2 中存在的任何元素数据对象的filter2,如果找到任何一个对象,则返回该对象

few example

结果为 {filter1:["mine"]: filter2:["F","D"]}

result = [
{ id:1, filter1:["mine"], filter2:["E","C"]}, //since filter1 "mine"
{ id:2, filter1:["mine"], filter2:["E","C","F"]}, //since filter1 "mine"
{ id:3, filter1:["your"], filter2:["D","C"]}, //since from "F" and "D" from filter2 "D" is present
{ id:5, filter1:["other"], filter2:["F"]}, //since "F" from filter2 is present
]

结果为 {filter1:["your"]: filter2:["F","G"]}

result = [
{ id:2, filter1:["mine"], filter2:["E","C","F"]}, //since "F" from filter2 is present
{ id:3, filter1:["your"], filter2:["D","C"]}, //since filter1 is "your"
{ id:5, filter1:["other"], filter2:["F"]}, //since "F" from filter2 is present
]

结果为 {filter1:[]: filter2:["D"]}

result = [
{ id:3, filter1:["your"], filter2:["D","C"]}, //since filter2 has "D"
]
4

2 回答 2

2

您可以使用.filter(),.some()和的组合.includes()

const data = [
  { id:1, filter1:["mine"], filter2:["E","C"]},
  { id:2, filter1:["mine"], filter2:["E","C","F"]},
  { id:3, filter1:["your"], filter2:["C"]},
  { id:3, filter1:["your"], filter2:["D","C"]},
  { id:5, filter1:["other"], filter2:["F"]}
];

const search = ({ filter1, filter2 }) => 
  data.filter(item => 
    item.filter1.some(fItem => filter1.includes(fItem)) ||
    item.filter2.some(fItem => filter2.includes(fItem))
);

const result = search({ filter1:["mine"], filter2:["F","D"] });
console.log(result);

于 2021-10-24T22:19:39.680 回答
1

您可以通过调用传递的过滤器对象的 来概括RoMilton 提出的解决方案,然后使用嵌套调用迭代每个和。some()Object.entries()keyfilter_arraysome()

如果您还将Array#concat()当前迭代的数据元素属性放入数组中,则可以在过滤器对象中包含非数组属性,即id在这种情况下。

const data = [
  { id: 1, filter1: ["mine"], filter2: ["E", "C"] },
  { id: 2, filter1: ["mine"], filter2: ["E", "C", "F"] },
  { id: 3, filter1: ["your"], filter2: ["C"] },
  { id: 3, filter1: ["your"], filter2: ["D", "C"] },
  { id: 5, filter1: ["other"], filter2: ["F"] }
];

const search = (array, filter_object) =>
  array.filter(item =>
    Object.entries(filter_object).some(([key, filter_array]) =>
      [].concat(item[key]).some(fitem => filter_array.includes(fitem)))
  );

const filter = { filter1: ["mine"], filter2: ["F", "D"] };
const result = search(data, filter);

console.log(...result.map(({ id }) => ({ id })));

const filter2 = { id: [5], filter1: ["mine"] }
const result2 = search(data, filter2);

console.log(...result2.map(({ id }) => ({ id })));
.as-console-wrapper { max-height: 100% !important; top: 0; }

这种使用concat()也可以应用于硬编码解决方案,以允许数据数组中可能不是数组的属性。

const data = [
  { id: 1, filter1: "mine", filter2: ["E", "C"] },
  { id: 2, filter1: ["mine"], filter2: ["E", "C", "F"] },
  { id: 3, filter1: ["your"], filter2: ["C"] },
  { id: 3, filter1: ["your"], filter2: ["D", "C"] },
  { id: 5, filter1: ["other"], filter2: ["F"] }
];

const search = ({ filter1, filter2 }) => (
  data.filter(item =>
    [].concat(item.filter1).some(fItem => filter1.includes(fItem)) ||
    [].concat(item.filter2).some(fItem => filter2.includes(fItem))
  ));

const result = search({ filter1: ["mine"], filter2: ["F", "D"] });
console.log(result);

于 2021-10-24T23:52:05.907 回答