基于此现有数组对象创建新的多维数组

时间:2018-06-11 04:38:36

标签: javascript multidimensional-array ecmascript-6

我很难根据现有的数组对象构建一个新的多维数组

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 :(得分:0)

您可以使用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对象需要是单独的引用,则可以使用spread:

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: [] })
);

答案 1 :(得分:0)

通常情况下我不会回答这个问题,但是告诉你使用reduce的人数正在扼杀我。

执行此操作的最佳方法(如果您只使用view / update / remove)将使用过滤器。他们实际上描述了你想要采取的行动。

const acl2 = {
  view: acl.filter(({view}) => view),
  update: acl.filter(({update}) => update),
  remove: acl.filter(({remove}) => remove),
};

答案 2 :(得分:0)

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
//       }
//     ]
//   }

答案 3 :(得分:-1)

您可以按如下方式使用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);