繁体   English   中英

按 Id 对数组中的对象进行分组 - JavaScript

[英]Group objects in an array by Id - JavaScript

我有一个对象数组,它有两个字段 id 和操作权限的类型

const array=[
{view: false, id: 1},
{create: false, id: 1},
{read: false, id: 1},
{update: false, id: 1},
{delete: false, id: 1},
{view: false, id: 2},
{create: false, id: 2},
{read: false, id: 2},
{update: false, id: 2},
{delete: false, id: 2},
]

我想将其转换为以下数组:

const permissions=[
{
id: 1,
view: false,
read: false,
create: false,
delete:false,
update:false
},
{
id: 2,
view: false,
read: false,
create: false,
delete:false,
update:false
}
]

您可以在更新Map时使用Array#reduce迭代数组,其中idkey ,其结果对象是value

最后,您会将每个id的分组对象作为此映射中的values

 const array = [ {view: false, id: 1}, {create: false, id: 1}, {read: false, id: 1}, {update: false, id: 1}, {delete: false, id: 1}, {view: false, id: 2}, {create: false, id: 2}, {read: false, id: 2}, {update: false, id: 2}, {delete: false, id: 2}, ]; const res = [... array.reduce((map, { id, ...elem }) => map.set(id, { ...(map.get(id) || { id }), ...elem }) , new Map) .values() ]; console.log(res);

这是一个工作示例,它也使用array.reduce但普通对象而不是 javascript Map对象。 解决方案也没有缩小。

const data = [
    { view: false, id: 1 },
    { create: false, id: 1 },
    { read: false, id: 1 },
    { update: false, id: 1 },
    { delete: false, id: 1 },
    { view: false, id: 2 },
    { create: false, id: 2 },
    { read: false, id: 2 },
    { update: false, id: 2 },
    { delete: false, id: 2 },
]

const merged = data.reduce((prev, current) => {

    // get the id.
    // make it to string as we use it as key and not index!
    const id = '' + current.id

    // create object if it does not already exist:
    if (!prev[id]) {
        prev[id] = {}
    }


    // store the given data, merge it with already
    // existing data under the id
    prev[id] = {
        ...prev[id],
        ...current
    }

    // return the results.
    return prev

}, {})

// now that we have merged togehter the objects, 
// extract them and push em together to an array:

const results = Object.keys(merged).map(k => merged[k])

console.log('results', results)

另一个例子,可能不如使用reduce 优雅,而是使用for of 和map 数据类型的简单版本。

 const array = [{ view: false, id: 1 }, { create: false, id: 1 }, { read: false, id: 1 }, { update: true, id: 1 }, { delete: false, id: 1 }, { view: false, id: 1 }, { create: false, id: 1 }, { read: false, id: 1 }, { update: false, id: 1 }, { delete: false, id: 1 }] const perm = {} for(let el of array){ const {id} = el perm[id] = perm[id] ? {...perm[id], "id": id} : {"id": id} for(let key in el){ if(key === 'id'){ continue } perm[id] = {...perm[id], [key]: el[key]} } } console.log("Permissions Map:", perm) const permissionsArray = Object.values(perm) console.log("Permissions Array:",permissionsArray)

只是为了一些锻炼; .reduce()Object.assign()可以很方便。 问题是,结果数组将是一个稀疏数组,对象项占据具有相应id值的索引。

 var a = [ {view: false, id: 1} , {create: false, id: 1} , {read: true, id: 1} , {update: false, id: 1} , {delete: false, id: 1} , {view: false, id: 2} , {create: false, id: 2} , {read: false, id: 2} , {update: true, id: 2} , {delete: false, id: 2} ], g = a.reduce((c,o) => ( c[o.id] = c[o.id] ? Object.assign(c[o.id],o) : o , c ),[]); console.log(g);

现在这只是一半的措施。 如果您处理稀疏数组,那么您应该确保稍后遍历它们的正确且有效的方法是使用for in循环或Object.keys() 否则,如果id非常稀疏,您可能会浪费大量时间检查漏洞。 即一个id是 1,下一个是 10000000。此外, .length属性还将包括未使用的索引。 不理想。

那么你可能会想,如果我们最终会得到一个稀疏数组,为什么我们需要一个数组来将它们分组? 所以一个好主意是将它们分组到另一个对象下。 根据您的逻辑,这可能会成为更好的抽象。 所以只是喜欢;

g = a.reduce((c,o) => ( c[o.id] = c[o.id] ? Object.assign(c[o.id],o)
                                          : o
                      , c
                      ),{});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM