Создать новый многомерный массив на основе этого существующего массива - PullRequest
0 голосов
/ 11 июня 2018

Я застрял, чтобы создать новый многомерный массив на основе этого существующего объекта массива

acl:[
{
   view:true, 
   update:true, 
   remove:true, 
   userId:1, 
   username:"Mike"
},
{
   view:true, 
   update:true, 
   remove:false, 
   userId:2, 
   username:"Joe"
},
{
   view:true, 
   update:false, 
   remove:false, 
   userId:3, 
   username:"Lim"
}
]

Новый объект будет построен на основе логических свойств (если эти логические значения равны true).Новый массив будет выглядеть так:

acl:[
{
view:[
   {username:"Mike", userId:1},
   {username:"Joe", userId:2},
   {username:"Lim", userId:3}
]
update:[
   {username:"Mike", userId:1},
   {username:"Joe", userId:2}
]
remove:[
   {username:"Mike", userId:1}
]

Я застрял на построении логики внутри итерации.Может, кто-нибудь подскажет мне об этом.

Ответы [ 4 ]

0 голосов
/ 11 июня 2018
const acl = [{"view":true,"update":true,"remove":true,"userId":1,"username":"Mike"},{"view":true,"update":true,"remove":false,"userId":2,"username":"Joe"},{"view":true,"update":false,"remove":false,"userId":3,"username":"Lim"}]

function multi_dim (array) {

  const res = {
    view: [],
    update: [],
    remove: []
  }

  const keys = Object.keys(array[0])

  for (let i = 0; i < array.length; i++) {
    keys.forEach(function (key) {
      if (key !== 'username' && key !== 'userId') {
        if (array[i][key]) {
          res[key].push({
            username: array[i].username,
            userId: array[i].userId
          })
        }
      }
    })
  }

  return res

}

let obj = multi_dim(acl) // returns object. Push to array if so desired

console.log(obj)

// => result
//   {
//     "view": [
//       {
//         "username": "Mike",
//         "userId": 1
//       },
//       {
//         "username": "Joe",
//         "userId": 2
//       },
//       {
//         "username": "Lim",
//         "userId": 3
//       }
//     ],
//     "update": [
//       {
//         "username": "Mike",
//         "userId": 1
//       },
//       {
//         "username": "Joe",
//         "userId": 2
//       }
//     ],
//     "remove": [
//       {
//         "username": "Mike",
//         "userId": 1
//       }
//     ]
//   }
0 голосов
/ 11 июня 2018

Вы можете использовать Array.prototype.reduce() следующим образом:

const permissions = ['view', 'update', 'remove'];
const output = acl.reduce((a, v) => {
  permissions.forEach(p => {
    if (v[p]) a[p].push({username: v.username, userId: v.userId});
  });

  return a;
}, permissions.reduce((a, p) => ({ ...a, [p]: []}), {}));

const acl = [{
    view: true,
    update: true,
    remove: true,
    userId: 1,
    username: "Mike"
  },
  {
    view: true,
    update: true,
    remove: false,
    userId: 2,
    username: "Joe"
  },
  {
    view: true,
    update: false,
    remove: false,
    userId: 3,
    username: "Lim"
  }];

const permissions = ['view', 'update', 'remove'];

const output = acl.reduce((a, v) => {
  permissions.forEach(p => {
    if (v[p]) a[p].push({username: v.username, userId: v.userId});
  });
  
  return a;
}, permissions.reduce((a, p) => ({ ...a, [p]: []}), {}));

console.log(output);
0 голосов
/ 11 июня 2018

Обычно я бы не ответил на это, но количество людей, говорящих вам, чтобы использовать сокращение, убивает меня.

Самый лучший способ сделать это (если вы работаете только с просмотром / обновлением / удалением)будет использовать фильтры.Они фактически описывают действие, которое вы пытаетесь предпринять.

const acl2 = {
  view: acl.filter(({view}) => view),
  update: acl.filter(({update}) => update),
  remove: acl.filter(({remove}) => remove),
};
0 голосов
/ 11 июня 2018

Вы можете использовать reduce для группировки в объект массивов:

const acl=[{view:!0,update:!0,remove:!0,userId:1,username:"Mike"},{view:!0,update:!0,remove:!1,userId:2,username:"Joe"},{view:!0,update:!1,remove:!1,userId:3,username:"Lim"}];

console.log(
  acl.reduce((a, { view, update, remove, userId, username }) => {
    const obj = { username, userId };
    if (view) a.view.push(obj);
    if (update) a.update.push(obj);
    if (remove) a.remove.push(obj);
    return a;
  }, { view: [], update: [], remove: [] })
);

Или, если объекты username / userId должны быть отдельными ссылками, вы можете использовать распространение:

const acl=[{view:!0,update:!0,remove:!0,userId:1,username:"Mike"},{view:!0,update:!0,remove:!1,userId:2,username:"Joe"},{view:!0,update:!1,remove:!1,userId:3,username:"Lim"}];

console.log(
  acl.reduce((a, { view, update, remove, userId, username }) => {
    const obj = { username, userId };
    if (view) a.view.push({...obj});
    if (update) a.update.push({...obj});
    if (remove) a.remove.push({...obj});
    return a;
  }, { view: [], update: [], remove: [] })
);
...