【问题标题】:How to get Main Array with the Object when filtering a Sub array过滤子数组时如何使用对象获取主数组
【发布时间】:2021-08-28 14:36:55
【问题描述】:

我有这个数据数组,当我过滤子数组时,orderedItems 对象键只被过滤而不是整个数据,这是我的代码。

const data = [
  {
    id: 6,
    orderedItems: [ { name: "Product A", vendor: 2 }, { name: "Product B", vendor: 2 }, { name: "Product B", vendor: 2 } ]
  },
  {
    id: 5,
    orderedItems: [ { name: "Product Aaa", vendor: 1 }, { name: "Product Bbb", vendor: 1 }, { name: "Product Ccc", vendor: 2 } ]
  }
];
const userId = 1;

const filteredData = data.map(({ id, orderedItems }) => {
  return {
    id: id,
    orderedItems: orderedItems.filter(({ vendor }) => vendor == userId),
  };
});

console.log(JSON.stringify(filteredData, null, 2));

结果:

[
  {
    "id": 6,
    "orderedItems": []
  },
  {
    "id": 5,
    "orderedItems": [ { "name": "Product Aaa", "vendor": 1 }, { "name": "Product Bbb", "vendor": 1 } ]
  }
]

预期结果:

[
  {
    "id": 5,
    "orderedItems": [ { "name": "Product Aaa", "vendor": 1 }, { "name": "Product Bbb", "vendor": 1 } ]
  }
]

过滤器有效,但仅适用于orderedItems 对象键,我也希望数组之外的id 也被过滤。有没有办法做到这一点?,如果您需要任何澄清或解释,请在下面评论。谢谢

【问题讨论】:

  • 请提供一个带有userId 和预期输出的清晰示例
  • 好的,我马上修改
  • 我已经编辑了问题并指定了我想要的内容
  • 所以你想过滤掉没有orderItems的结果对象?
  • 是的,类似的

标签: javascript arrays filter


【解决方案1】:

您可以使用Array#reduce 遍历列表并在每次迭代中计算当前项的过滤顺序,如果它不为空,则将其与当前id 一起添加到累加器中:

const 
  data = [
    { id: 6, orderedItems: [ { name: "Product A", vendor: 2 }, { name: "Product B", vendor: 2 }, { name: "Product B", vendor: 2 } ] },
    { id: 5, orderedItems: [ { name: "Product Aaa", vendor: 1 }, { name: "Product Bbb", vendor: 1 }, { name: "Product Ccc", vendor: 2 } ] }
  ],
  userId = 1;

const filteredData = data.reduce((filteredItems, { id, orderedItems }) => {
  const itemFilteredOrders = orderedItems.filter(({ vendor }) => vendor == userId);
  if(itemFilteredOrders.length > 0) {
    filteredItems.push({ id, orderedItems: itemFilteredOrders });
  }
  return filteredItems;
}, []);

console.log(JSON.stringify(filteredData, null, 2));

完成您的方法的另一种方法是按orderedItems 的长度过滤结果列表:

const 
  data = [
    { id: 6, orderedItems: [ { name: "Product A", vendor: 2 }, { name: "Product B", vendor: 2 }, { name: "Product B", vendor: 2 } ] },
    { id: 5, orderedItems: [ { name: "Product Aaa", vendor: 1 }, { name: "Product Bbb", vendor: 1 }, { name: "Product Ccc", vendor: 2 } ] }
  ],
  userId = 1;

const filteredData = data
  .map(({ id, orderedItems }) => ({
    id,
    orderedItems: orderedItems.filter(({ vendor }) => vendor == userId)
  }))
  .filter(({ orderedItems }) => orderedItems.length > 0);

console.log(JSON.stringify(filteredData, null, 2));

【讨论】:

  • 感谢您的回答,这正是我所需要的,感谢您还提供了使用选项:))
【解决方案2】:

您可以使用Array#reduce 遍历并跟踪data 数组中的每个匹配项。和Array#filter 过滤掉.orderedItems 中不满足条件的项。

完整代码:

const data = [ { id: 6, orderedItems: [ { name: 'Product A', vendor: 2, }, { name: 'Product B', vendor: 2, }, { name: 'Product B', vendor: 2, }, ], }, { id: 5, orderedItems: [ { name: 'Product Aaa', vendor: 1, }, { name: 'Product Bbb', vendor: 1, }, { name: 'Product Ccc', vendor: 2, }, ], }, ];

const userId = 1;

let res = data.reduce((acc, obj) => {
  let passed = obj.orderedItems.filter((subObj) => subObj.vendor === userId);
  if (passed.length) acc.push({ ...obj, orderedItems: passed });
  return acc;
}, []);

console.log(res)

【讨论】:

  • 感谢您的回答,我已经为这个问题投票了
【解决方案3】:

您可以使用方法过滤器来选择与 userId 匹配的所有 id,然后继续执行您的代码:

const filteredData = data.filter(el => el.id === userId).map(({ id, orderedItems }) => {
  return {
    id: id,
    orderedItems: orderedItems.filter(({ vendor }) => vendor == userId),
  };
});```
   

【讨论】:

    猜你喜欢
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 2020-07-11
    • 2021-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-14
    相关资源
    最近更新 更多