微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用来自另一个数组的匹配对象过滤数组并将其推送到新数组?

如何解决如何使用来自另一个数组的匹配对象过滤数组并将其推送到新数组?

我有以下数据数组,我想按公司名称/名称过滤。

data = [
   {
      "company":{
         "name":"Company 1","symbol":"one"
      },"description":"test","status":"Pending"
   },{
      "company":{
         "name":"Company 2","symbol":"two"
      },{
      "company":{
         "name":"Company 3","symbol":"three"
      },{
      "company":{
         "name":"Company 1","symbol":"four"
      },"description":"testrr","status":"Pending"
   }
]
filterBy = ["Company 1","Company 3"]

预期结果

filteredData = [
   {
      "companyName":"Company 1","matchingData":[
         {
            "company":{
               "name":"Company 1","symbol":"one"
            },"status":"Pending"
         },{
            "company":{
               "name":"Company 1","symbol":"four"
            },"status":"Pending"
         }
      ]
   },{
      "companyName":"Company 3","matchingData":[
         {
            "company":{
               "name":"Company 3","symbol":"three"
            },"status":"Pending"
         }
      ]
   }
]

尝试

使用以下尝试,我将获得所有匹配的对象,而不是单独获取每个匹配

const result = data.filter((obj) => filterBy.includes(obj.company.name));
let expectedResult = []
 filterBy.forEach((e,i )=> {
      let d = {companyName:e[i],matchingData: result}
      expectedResult .push(d)
    });

..................................... ………………………………………………………………………………………………………………………………………………………… ………………………………………………………………………………………………………………………………………………………… ......

解决方法

每个输出项中的 matchingData 属性不需要是 result,它是整个过滤后的数组,而是一个包含单个元素的数组,其中该元素是过滤后的项迭代。

您也可以使用 .map 代替 .push 使事情更简洁。

data = [
   {
      "company":{
         "name":"Company 1","symbol":"one"
      },"description":"test","status":"Pending"
   },{
      "company":{
         "name":"Company 2","symbol":"two"
      },{
      "company":{
         "name":"Company 3","symbol":"three"
      },"status":"Pending"
   }
]
filterBy = ["Company 1","Company 3"]

const result = data
  .filter((obj) => filterBy.includes(obj.company.name))
  .map(item => ({
    companyName: item.company.name,matchingData: [item]
  }));
console.log(result);

如果输入数组中的多个项目可能有相同的公司,并且这些相同的公司应该在输出中分组 - 例如

filteredData = [
   {
      "companyName":"Company 1","matchingData":[
          <some company 1 object>,<some other company 1 object>,

那么你需要更详细一点。创建一个对象,其键是 companyName,值是数组。

data = [
   {
      "company":{
         "name":"Company 1","Company 3"]

const filtered = data.filter((obj) => filterBy.includes(obj.company.name));
const grouped = {};
for (const item of filtered) {
  const { name } = item.company;
  grouped[name] ??= [];
  grouped[name].push(item);
}
const result = Object.entries(grouped).map(
  ([companyName,matchingData]) => (
    { companyName,matchingData }
  ));
console.log(result);

,

由于您即时更改了问题所需的输出 - 我猜您没有严格执行该确切输出 - 因此这是一个更好的输出

我建议更好的输出,这是一个对象 - 其中键是实际的公司名称(因为它们无论如何都是唯一的!){"Company 1": [{},{}],"Company 3": [{}]} 创建所需的代码由于 Array.prototype.reduce()

,这样的输出将是显而易见的

const data = [{"company":{"name":"Company 1","symbol":"one"},"status":"Pending"},{"company":{"name":"Company 2","symbol":"two"},{"company":{"name":"Company 3","symbol":"three"},{"company":{"name":"Company 1","symbol":"four"},"description":"testrr","status":"Pending"}];

const filterBy = ["Company 1","Company 3"];

const filteredData = data.reduce((ob,data) => {
  const n = data.company.name;
  if (filterBy.includes(n)) {
    if (!ob[n]) ob[n] = [];
    ob[n].push(data);
  }
  return ob;
},{});

console.log(filteredData); // {"Company 1": [{..},{..}],"Company 3",[{..}]}

上面的美妙之处在于,稍后您可以使用以下方法轻松提取所需的列表:

const items_of_comp_1 = filteredData["Company 1"];
console.log(items_of_comp_1); // [{...},{...}]

或者,如果您想循环 filteredData 对象,您可以使用以下方法轻松完成:Object.entries()Object.keys()Object.values() 方法!


编辑前的旧答案

您已经很接近了,但是 .forEach() 和 .map() 并不是要创建子集。 .filter() 也不在游戏中,因为您需要稍微修改的输出。因此使用 .reduce():

  • 使用 Array.prototype.reduce() 将数组缩减为经过过滤但已修改的项目集
  • 使用 Array.prototype.includes()(您已经使用过)检查数组是否包含特定项

const data = [{"company":{"name":"Company 1","status":"Pending"}];
const filterBy = ["Company 1","Company 3"]

const filteredData = data.reduce((a,matchingData) => {
  const companyName = matchingData.company.name;
  if (filterBy.includes(companyName)) a.push({companyName,matchingData});
  return a;
},[]);

console.log(filteredData)

,

这是我为公司 1 和公司 3 过滤的代码

https://codepen.io/tmixab/pen/poPrxWJ

data = [
   {
      "company":{
         "name":"Company 1","status":"Pending"
   }
]

filterBy = ["Company 1","Company 3"];

const result = data.filter((obj) => filterBy.includes(obj.company.name));

console.log(JSON.stringify(result,null,4));

/*
let expectedResult = []
 filterBy.forEach((e,i )=> {
      let d = {companyName:e[i],matchingData: result}
      expectedResult.push(d)
    });
*/

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。