根据以数组形式存在于对象值内的值搜索对象数组

Posted

技术标签:

【中文标题】根据以数组形式存在于对象值内的值搜索对象数组【英文标题】:searching an array of objects on the basis of value present inside an value of an object in form of array 【发布时间】:2021-10-24 21:52:37 【问题描述】:

我有一个对象,其中有两个字段 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"],
...
]

我必须过滤掉那些在特定键中存在任何字段的对象 例如,如果filterfilter1:["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"
]

【问题讨论】:

你可以使用 Array.prototype.filter()。 【参考方案1】:

您可以使用.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);

【讨论】:

如果filter1不是这样的数组形式 const data = [ id:1, filter1:"mine", filter2:["E","C"], id :2,过滤器1:“我的”,过滤器2:[“E”,“C”,“F”],];那么使用 some 会抛出错误如何处理 在我的回答中查看concat() 的使用来解决这个问题。 是的,@pilchard 是正确的。将item.filter1.some 替换为[].concat(item.filter1).some,并对下一行执行相同操作。然后它将处理包含字符串而不是数组的数据。【参考方案2】:

您可以通过在传递的过滤器对象的Object.entries() 上调用some() 来概括solution proposed by RoMilton,然后使用嵌套的some() 调用迭代每个keyfilter_array

如果您还 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);

【讨论】:

以上是关于根据以数组形式存在于对象值内的值搜索对象数组的主要内容,如果未能解决你的问题,请参考以下文章

如何根据 JavaScript 中的值检查对象是不是在数组中?

Mongoose:如果值存在于对象数组中的数组中,则过滤数据

如何使用 mongodb 在对象内迭代数组

在javascript中搜索对象中的值[关闭]

展平数组内的对象

Laravel - 根据键值删除数组内的对象 - array_filter