将深层嵌套的属性提取到唯一值数组中

时间:2020-03-31 12:38:56

标签: javascript angular rxjs

考虑到以下JSON是我的对象,如何提取userId和角色,将它们分别存储在单独的数组中,而没有任何重复的值。

let rosterInfo = 
    [
        {
           "shiftName": "A",
            "userDetail": [
            {
              "userId": 'Mary',
              "roles": ['Operator', 'Supervisor']
            },
            {
              "userId": 'John',
              "roles": ['Supervisor', Maintenance Technician]
            }
          ]
        },
        {
           "shiftName": "B",
          "userDetail": [
            {
              "userId": 'Crusier',
              "roles": ['Operator', 'Supervisor']
            },
            {
              "userId": 'Philips',
              "roles": ['Operator', 'Supervisor']
            }
          ]
        },
        {
           "shiftName": "C",
             "userDetail": [
            {
              "userId": 'Heath',
              "roles": ['Operator', 'Supervisor']
            },
            {
              "userId": 'Daniel',
              "roles": ['Operator', 'Supervisor']
            }
          ]
        }
    ];

角色的最终排列应为:['操作员,'主管','维护技术员'] userId的最终数组应为:['Heath','Daniel','Philips','John','Mary','Crusier']

注意:我已经使用了ForEach和For循环,但这并不是理想的解决方案。这是我使用循环的解决方案。

  rosterInfo.forEach(rosterItem => {
  for (let userItem of rosterItem['userDetail']) {
    userItem['roles'].forEach(role => {
      this.rolesInAShift.indexOf(role) > -1
        ? ''
        : this.rolesInAShift.push(role);
    });
  }
});

除了上述对象中提供的所有对象之外,如果我完全想过滤名称为“ John”和“ Supervisor”角色的对象,那么最终将是这种类型的对象。

rosterInfo = 
    [
        {
           "shiftName": "A",
            "userDetail": [
            {
              "userId": 'John',
              "roles": ['Supervisor', 'Maintenance Technician']
            }

          ]
        },
        {
           "shiftName": "B",
          "userDetail": [

          ]
        },
        {
           "shiftName": "C",
             "userDetail": [

          ]
        }
    ]

我能够使用循环来实现这一点,但是使用下面的逻辑并不能得到我想要的东西。

 someVar = rosterInfo.map(element => {
        return {
          ...element,
          userDetail: element.userDetail.filter(
            subElement =>
              subElement.roles.indexOf('Supervisor') > -1 &&
              subElement.userId.indexOf('Rajasekhar')
          )
        };
      });

2 个答案:

答案 0 :(得分:3)

您可以将Array.prototype.map()Set()一起使用以删除重复项:

const rosterInfo = 
    [{"shiftName":"A","userDetail":[{"userId":'Mary',"roles":['Operator','Supervisor']},{"userId":'John',"roles":['Supervisor','Maintenance Technician']}]},{"shiftName":"B","userDetail":[{"userId":'Crusier',"roles":['Operator','Supervisor']},{"userId":'Philips',"roles":['Operator','Supervisor']}]},{"shiftName":"C","userDetail":[{"userId":'Heath',"roles":['Operator','Supervisor']},{"userId":'Daniel',"roles":['Operator','Supervisor']}]}],
    
    userIds = [...new Set(
      rosterInfo
        .map(({userDetail}) =>
          userDetail.map(({userId}) => userId))
        .flat()
    )],
    
    roles = [...new Set(
      rosterInfo
        .map(({userDetail}) => 
          userDetail.map(({roles}) => roles))
        .flat(2)
    )]
    
console.log(userIds)
console.log(roles)
.as-console-wrapper{min-height:100%;}

答案 1 :(得分:1)

使用reduceSet可以轻松完成。减少循环,设置为唯一。请检查样本。

let rosterInfo = [
  {
    shiftName: "A",
    userDetail: [
      { userId: "Mary", roles: ["Operator", "Supervisor"] },
      { userId: "John", roles: ["Supervisor", "Maintenance Technician"] }
    ]
  },
  {
    shiftName: "B",
    userDetail: [
      { userId: "Crusier", roles: ["Operator", "Supervisor"] },
      { userId: "Philips", roles: ["Operator", "Supervisor"] }
    ]
  },
  {
    shiftName: "C",
    userDetail: [
      { userId: "Heath", roles: ["Operator", "Supervisor"] },
      { userId: "Daniel", roles: ["Operator", "Supervisor"] }
    ]
  }
];
const [roles, names] = rosterInfo.reduce(
  ([roles, names], i) => {
    i.userDetail.forEach(x => {
      roles = roles.concat(x.roles);
      names.push(x.userId);
    });
    return [roles, names];
  },
  [[], []]
);
console.log(Array.from(new Set(roles)), Array.from(new Set(names)));