JavaScript - 来自匹配ID的新对象数组

问题描述 投票:1回答:4

我只是想知道使用ES6在JavaScript中处理此问题的最佳方法。

使用以下数据:

categories: [
    {id: 1,name: "category 1",items: [19993, 99737]},
    {id: 2,name: "category 2",items: [70264, 65474, 07078]},
    {id: 3,name: "category 3",items: [76765]}
]

items: [
    {id: 19993, name: "item 1"},
    {id: 70264, name: "item 2"},
    {id: 99737, name: "item 3"},
    {id: 65474, name: "item 4"},
    {id: 76765, name: "item 5"},
    {id: 07078, name: "item 6"}
]

我正在尝试根据categories.items数组中包含的ID为每个类别创建一个新的项目数组。

所以对于类别1,输出应该是:

[
    {id: 19993, name: "item 1"},
    {id: 99737, name: "item 3"}
]

我知道我可以通过乱七八糟的循环来做这个,推进阵列但是想知道是否有更短的ES6实现这个方法?

谢谢

javascript ecmascript-6
4个回答
1
投票

您可以找到类别和项目。

function getItemsByCategory(id) {
    var category = categories.find(o => o.id === id);
    if (category) {
        return category.items.map(id => items.find(o => o.id === id));
    }
}

var categories = [{ id: 1, name: "category 1", items: [19993, 99737] }, { id: 2, name: "category 2", items: [70264, 65474, 07078] }, { id: 3, name: "category 3", items: [76765] }],
    items = [{ id: 19993, name: "item 1" }, { id: 70264, name: "item 2" }, { id: 99737, name: "item 3" }, { id: 65474, name: "item 4" }, { id: 76765, name: "item 5" }, { id: 07078, name: "item 6" }];

console.log(getItemsByCategory(1));
.as-console-wrapper { max-height: 100% !important; top: 0; }

2
投票

根据Map数组中的id项创建items。使用Array.map()迭代categories数组。对于每个类别,使用object spread创建一个新对象,并从Map填充items数组:

const categories = [{"id":1,"name":"category 1","items":[19993,99737]},{"id":2,"name":"category 2","items":[70264,65474,7078]},{"id":3,"name":"category 3","items":[76765]}]

const items = [{"id":19993,"name":"item 1"},{"id":70264,"name":"item 2"},{"id":99737,"name":"item 3"},{"id":65474,"name":"item 4"},{"id":76765,"name":"item 5"},{"id":7078,"name":"item 6"}]

const itemsMap = new Map(items.map(o => [o.id, o]))

const result = categories.map(o => ({
  ...o,
  items: o.items.map(id => itemsMap.get(id))
}))

console.log(result)

2
投票

你可以使用Array.prototype.map()Array.prototype.find()Array.prototype.filter()简洁地完成:

const categories = [
    {id: 1,name: "category 1",items: [19993, 99737]},
    {id: 2,name: "category 2",items: [70264, 65474, 07078]},
    {id: 3,name: "category 3",items: [76765]}
];

const items = [
    {id: 19993, name: "item 1"},
    {id: 70264, name: "item 2"},
    {id: 99737, name: "item 3"},
    {id: 65474, name: "item 4"},
    {id: 76765, name: "item 5"},
    {id: 07078, name: "item 6"}
];

const result = categories.map(c => ({
    ...c,
    items: c.items.map(id => items.find(i => id === i.id)).filter(Boolean)
}));

console.log(result);

1
投票

你可以使用reduceforEachfind

这里的想法是

  • 首先,对于类别中的每个项目数组,我们在items变量中找到匹配元素。
  • 如果我们找到匹配元素,我们将其添加到op else,返回op而不做任何更改

let categories = [{id: 1,name: "category 1",items: [19993, 99737]},{id: 2,name: "category 2",items: [70264, 65474, 07078]},{id: 3,name: "category 3",items: [76765]}]
let items = [{id: 19993, name: "item 1"},{id: 70264, name: "item 2"},{id: 99737, name: "item 3"},   {id: 65474, name: "item 4"},{id: 76765, name: "item 5"},{id: 07078, name: "item 6"},]

let op = categories.reduce((op, {name, items:cartItems}) => {
  cartItems.forEach(key => {
    let value = items.find(({id}) => id === key)
    if(value){
      op[name] = op[name] || []
      op[name].push(value)
    }
  })
  return op
},{})

console.log(op)
© www.soinside.com 2019 - 2024. All rights reserved.