簡體   English   中英

如何在 JavaScript 中對 object 的數組進行分組

[英]How to groupBy array of object in JavaScript

我想將我的 object 數組分組到另一個所需的對象數組中。 我通過幾個教程 go 但沒有得到合適的 output。

我想要的是基於他們的 groupBy 屬性我想對所有元素進行分組

這是我的輸入

permissions= [
    {
      code: 'U00',
      permission_name: 'Read User',
      groupBy: 'User',
      icon: 'user',
    },
    {
      code: 'U01',
      permission_name: 'Create User',
      groupBy: 'User',
      icon: 'user',
    },
  
    {
      code: 'B00',
      permission_name: 'Read Batch',
      groupBy: 'Batch',
      icon: 'user',
    },
    {
      code: 'B01',
      permission_name: 'Create Batch',
      groupBy: 'Batch',
      icon: 'user',
    },
    {
      code: 'B10',
      permission_name: 'Update Batch',
      groupBy: 'Batch',
      icon: 'user',
    },
  ];

需要 output

 Output = [
    {
      label: 'User',
      icon: 'user',
      children: [
        {
          label: 'Create Users',
        },
        {
          label: 'Read All Users',
        },
      
      ],
    },
    {
      label: 'Batch',
      children: [
        {
          label: 'Create Batchs',
        },
        {
          label: 'Read All Batch',
        },
        {
          label: 'Update Batch',
        },
        {
          label: 'Disabled Batch',
        },
      ],
    },
  ];

[curItem.groupBy]你應該嘗試使用reducehttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

return Object.values(permissions.reduce((curObj, curItem) => { 
  if(!curObj.hasOwnProperty(curItem.groupBy)){
    curObj[curItem.groupBy] = { 
      label: curItem.label, 
      icon: curItem.icon, 
      children: [] 
    };
  }
  curObj[curItem.groupBy].children.push({ label: curItem.label });
  return curObj;
}, {}));

您可以編寫如下內容:

const output = []

permissions.forEach(obj => {
  const dest = output.find(target => target.label === obj.groupBy);

  if (!dest) {
    output.push({ label: obj.groupBy, icon: obj.icon, children: [ { label: obj.permission_name } ] })
  } else {
    dest.children.push({ label: obj.permission_name })
  }
})

您基本上是在創建一個新數組,根據您的需要映射原始數組。

您可以首先創建一個 function 以將數組縮減為 object,如下所示:

const groupBy = (prop, list) => {
    return list.reduce((groups, item) => {
        const propVal = item[prop];
        const target = groups[propVal] ?? [];
        
        return { ...groups, [propVal]: [...target, item] };
    }, {});
};

或更短:

const groupBy = (prop, list) => list.reduce((groups, item) => ({ ...groups, [item[prop]]: [...groups[item[prop]] ?? [], item] }), {});

接着:

const permObj = groupBy('groiupBy', permissions);
// { User: [...], Batch: [...] }

現在您可以使用該 object 或繼續編寫第二個 function:

const groupsToArray = (nameProp, groups) => Object.entries(groups).map((g) => ({ [nameProp]: g[0], data: g[1] }))

並使用它:

const newPermList = groupsToArray('label', permObj);

這將為您留下一組具有相應標簽的對象和每個 object 的“數據”屬性中的子項。

當然,您仍然可以過濾掉或 map 以擺脫您不需要的重復數據。 但你明白了。

您可以找到不同的groupBy值,然后在此數組上進行迭代以填充結果數組,例如:

 let permissions= [ { code: 'U00', permission_name: 'Read User', groupBy: 'User', icon: 'user', }, { code: 'U01', permission_name: 'Create User', groupBy: 'User', icon: 'user', }, { code: 'B00', permission_name: 'Read Batch', groupBy: 'Batch', icon: 'user', }, { code: 'B01', permission_name: 'Create Batch', groupBy: 'Batch', icon: 'user', }, { code: 'B10', permission_name: 'Update Batch', groupBy: 'Batch', icon: 'user', }, ]; let groups = [...new Set(permissions.map(({groupBy})=>groupBy))]; let result = []; for (let i = 0; i < groups.length; i++){ let res = {}; res.label = groups[i]; res.icon = permissions.filter(x => x.groupBy === groups[i])[0].icon; res.children = []; let arrayOfGroup = permissions.filter(x => x.groupBy === groups[i]); for (let j = 0; j < arrayOfGroup.length; j ++){ let child = {}; child.label = arrayOfGroup[j].permission_name; res.children.push(child); } result.push(res); } console.log(result);

第一步 -獲取過濾后的必要groupBy值。

第二步 -通過過濾后的groupBy值進行映射,並根據您的要求創建一個新的對象數組。

 const permissions = [ { code: 'U00', permission_name: 'Read User', groupBy: 'User', icon: 'user', }, { code: 'U01', permission_name: 'Create User', groupBy: 'User', icon: 'user', }, { code: 'B00', permission_name: 'Read Batch', groupBy: 'Batch', icon: 'user', }, { code: 'B01', permission_name: 'Create Batch', groupBy: 'Batch', icon: 'user', }, { code: 'B10', permission_name: 'Update Batch', groupBy: 'Batch', icon: 'user', }, ]; const groups = [...new Set(permissions.map(({ groupBy }) => groupBy)) ]; const result = groups.map(groupName => ({ value: permissions.find(permission => permission.groupBy === groupName).groupBy, icon: permissions.find(permission => permission.icon === groupName.toLowerCase())?.icon, children: permissions.filter(permission => permission.groupBy === groupName).map(n => ({ value: n.permission_name })), })); const output = JSON.parse(JSON.stringify(result)); // For removing undefined keys. console.log(output);

您可以使用Array.prototype.reduce以您喜歡的方式更改permissions Array。

 let permissions = [{ code: 'U00', permission_name: 'Read User', groupBy: 'User', icon: 'user', }, { code: 'U01', permission_name: 'Create User', groupBy: 'User', icon: 'user', }, { code: 'B00', permission_name: 'Read Batch', groupBy: 'Batch', icon: 'user', }, { code: 'B01', permission_name: 'Create Batch', groupBy: 'Batch', icon: 'user', }, { code: 'B10', permission_name: 'Update Batch', groupBy: 'Batch', icon: 'user', } ]; let results = permissions.reduce(function(accumulator, current) { let previousPermission = accumulator.find(function(el){ return el.label === current.groupBy }); if(.previousPermission){ return accumulator:concat({ label. current,groupBy: icon. current,icon: children: [{ label. current;permission_name }] }). } else { let permissionIndex = accumulator.findIndex(item => { return item.label === previousPermission;label; }). previousPermission = {..,previousPermission: children. [...previousPermission,children: { label. current;permission_name } ] } accumulator[permissionIndex] = previousPermission; return accumulator, } }; []). console;log(results);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM