繁体   English   中英

如何使用map(),reduce()和filter()简化javascript嵌套数组?

[英]How to simplify javascript nested array with map(), reduce(), and filter()?

首先,我是Javascript,ES6等的新手,我来自Java背景。 我有一个复杂的javascript数组结构(下面给出的例子),我试图将这个数组转换成一个映射(类似于Java的方式,键值对类的东西),key是权限名称(例如KEY-1,KEY) -2,KEY-3,KEY-4,KEY-5关于下面的javascript数组示例)而value是实际权限的逗号分隔值。 我可以通过循环b通过嵌套数组来实现它,但循环是我试图避免在这里,并希望使用map()/ reduce()/ filter()

以下是地图应如何包含数据的示例。 由于KEY-2存在于两个数组中,因此它们将被重写为一个(完全没问题)

KEY-1 = ["Roles.Create","Roles.Edit"]
KEY-2 = ["API-Admin.Create","API-Admin.Edit","API-Admin.Read"]
KEY-3 = ["Roles.Create","Roles.Edit"]
KEY-4 = ["Users.Read"]      
KEY-5 = ["Roles.Create","Roles.Edit"]

Javascript数组

const teamArr = [
  {
    "name":"Team1",
    "accountId":"Billing",
    "teamId":"12345",
    "permissions": {
        "KEY-1": [
            "Roles.Create",
            "Roles.Edit"
        ],
        "KEY-2": [
            "API-Admin.Create",
            "API-Admin.Edit",
            "API-Admin.Read"
        ],
        "KEY-3": [
          "Roles.Create",
          "Roles.Edit"
        ]
     }
   },
   {
     "name":"Team2",
     "accountId":"Sales",
     "teamId":"6789",
     "permissions": {
         "KEY-4": [
             "Users.Read"
         ],
         "KEY-2": [
            "API-Admin.Create",
            "API-Admin.Edit",
            "API-Admin.Read"
        ],
         "KEY-5": [
           "Roles.Create",
           "Roles.Edit"
         ]
      }
   }
]

KEY-1,KEY-2,KEY-3,KEY-4,KEY-5等都是动态生成的,所以我不能将这些键名硬编码到我的代码中(如KEY-1,KEY-2等)

我关注这篇文章https://www.freecodecamp.org/news/15-useful-javascript-examples-of-map-reduce-and-filter-74cbbb5e0a1f/以下是我试过的但是我想,我正在努力在复杂的javascript数组上正确使用sort()/ reduce()。 我更喜欢简单的Javascript / ES6解决方案(没有JQuery请)。

const sorted = test.sort((a, b) => a.permissions - b.permissions);
// Using reduce:
dict = sorted.reduce(
    (dict, el, index) => (dict[el.permissions] = sorted.length - index, dict),
    {}
);

console.log(dict)

这里的任何帮助将非常感激。 谢谢

你可以使用flatMapreduce的组合来做到这一点(尽管所有浏览器都不支持flatMap ):

 const teamArr = [{ "name": "Team1", "accountId": "Billing", "teamId": "12345", "permissions": { "KEY-1": [ "Roles.Create", "Roles.Edit" ], "KEY-2": [ "API-Admin.Create", "API-Admin.Edit", "API-Admin.Read" ], "KEY-3": [ "Roles.Create", "Roles.Edit" ] } }, { "name": "Team2", "accountId": "Sales", "teamId": "6789", "permissions": { "KEY-4": [ "Users.Read" ], "KEY-2": [ "API-Admin.Create", "API-Admin.Edit", "API-Admin.Read" ], "KEY-5": [ "Roles.Create", "Roles.Edit" ] } } ] const result = teamArr .flatMap(t => Object.entries(t.permissions)) .reduce((acc, [key, permissions]) => { acc[key] = acc[key] || []; acc[key].push(...permissions.filter(p => !acc[key].includes(p))); return acc; }, {}); console.log(result); 

如果密钥的权限数组可能非常大,您还可以考虑在累加器中使用每个密钥旁边的Set

由于您不需要担心其他键/值,因此首先需要创建一个包含所有permissions对象的数组。 然后从该数组中提取属性,使用Sets保持数组唯一:

 const teamArr = [{"name":"Team1","accountId":"Billing","teamId":"12345","permissions":{"KEY-1":["Roles.Create","Roles.Edit"],"KEY-2":["API-Admin.Create","API-Admin.Edit","API-Admin.Read"],"KEY-3":["Roles.Create","Roles.Edit"]}},{"name":"Team2","accountId":"Sales","teamId":"6789","permissions":{"KEY-4":["Users.Read"],"KEY-2":["API-Admin.Create","API-Admin.Edit","API-Admin.Read"],"KEY-5":["Roles.Create","Roles.Edit"]}}]; const res = teamArr.flatMap(({ permissions }) => Object.entries(permissions)).reduce((a, [k, v]) => ((a[k] = [...new Set(((a[k] = a[k] || []).push(...v), a[k]))], a)), {}); console.log(res); 
 .as-console-wrapper { max-height: 100% !important; top: auto; } 

更详细的版本:

 const teamArr = [{"name":"Team1","accountId":"Billing","teamId":"12345","permissions":{"KEY-1":["Roles.Create","Roles.Edit"],"KEY-2":["API-Admin.Create","API-Admin.Edit","API-Admin.Read"],"KEY-3":["Roles.Create","Roles.Edit"]}},{"name":"Team2","accountId":"Sales","teamId":"6789","permissions":{"KEY-4":["Users.Read"],"KEY-2":["API-Admin.Create","API-Admin.Edit","API-Admin.Read"],"KEY-5":["Roles.Create","Roles.Edit"]}}]; const permissions = teamArr.map(({ permissions }) => permissions); const res = permissions.flatMap(Object.entries).reduce((a, [k, v]) => { a[k] = a[k] || []; a[k].push(...v); a[k] = [...new Set(a[k])]; return a; }, {}); console.log(res); 
 .as-console-wrapper { max-height: 100% !important; top: auto; } 

const teamArr = [
  {
    "name":"Team1",
    "accountId":"Billing",
    "teamId":"12345",
    "permissions": {
        "KEY-1": [
            "Roles.Create",
            "Roles.Edit"
        ],
        "KEY-2": [
            "API-Admin.Create",
            "API-Admin.Edit",
            "API-Admin.Read"
        ],
        "KEY-3": [
          "Roles.Create",
          "Roles.Edit"
        ]
     }
   },
   {
     "name":"Team2",
     "accountId":"Sales",
     "teamId":"6789",
     "permissions": {
         "KEY-4": [
             "Users.Read"
         ],
         "KEY-2": [
            "API-Admin.Create",
            "API-Admin.Edit",
            "API-Admin.Read"
        ],
         "KEY-5": [
           "Roles.Create",
           "Roles.Edit"
         ]
      }
   }
];



function extractPermissions(obj) {
    const perms = {};
    obj.forEach(entry => {
        if (!entry['permissions']) {
            return;
        }
        Object.keys(entry.permissions).forEach(key => {
            if (!perms[key]) {
                perms[key] = [];
            }
            entry.permissions[key].forEach(value => {
                if (!perms[key].some(val => val === value)) {
                    perms[key].push(value);
                }
            });
        });
    });
    return perms;
}
console.log(JSON.stringify(extractPermissions(teamArr), null, 2));

暂无
暂无

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

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