Javascript-将给定对象简化为一个数据结构

时间:2019-08-07 04:55:42

标签: javascript

我需要将给定的对象简化为某种数据结构。这是我的输入对象。

const receiver =  {
      USER1: {
        module: ['a_critical', 'a_normal','b_normal']
      },
      USER2: {
        module: ['a_critical', 'a_normal','b_critical']
      }, 
      USER3: {
        module: ['a_critical']
      }
    };

const allModules = ['a_normal', 'a_critical', 'b_normal', 'b_critical']; 

所需的输出:

{
  "a_critical": [
    {
      "user": [
        "USER1", "USER2", "USER3"
      ]
    }
  ],
  "a_normal": [
    {
      "user": [
        "USER1", "USER2"
      ]
    }
 ],
  "b_normal": [
    {
      "user": [
        "USER1"
      ]
    }
  ],
  "b_critical": [
    {
      "user": [
        "USER2"
      ]
    }
  ]
} 

我尝试做,但是遇到了一些问题。我得到一些应该存在的重复属性。我可以分享自己尝试过的代码。

const receiverObj = {};

let count = 0;
Object.keys(receiver).forEach((item) => {
    receiver[item].module.forEach((module) => {
      if(allModules.includes(module)) {
        count  = 1;
        if(count) {
        receiverObj[module] = [];
           receiverObj[module].push({user: [item] });
        }
        receiverObj[module].push({user: item });
        count = 0;
      }
    })
});

console.log(JSON.stringify(receiverObj, null, 2)); 

我得到的实际结果:

{
  "a_critical": [
    {
      "user": [
        "USER3"
      ]
    },
    {
      "user": "USER3"
    }
  ],
  "a_normal": [
    {
      "user": [
        "USER2"
      ]
    },
    {
      "user": "USER2"
    }
  ],
  "b_normal": [
    {
      "user": [
        "USER1"
      ]
    },
    {
      "user": "USER1"
    }
  ],
  "b_critical": [
    {
      "user": [
        "USER2"
      ]
    },
    {
      "user": "USER2"
    }
  ]
} 

有什么最佳方法吗?有人可以帮忙吗?

5 个答案:

答案 0 :(得分:4)

在reduce回调中遍历每个module,如果还不存在,则在累加器中创建一个{ user: [] }对象,然后推送到该数组:

const receiver =  {
      USER1: {
        module: ['a_critical', 'a_normal','b_normal']
      },
      USER2: {
        module: ['a_critical', 'a_normal','b_critical']
      }, 
      USER3: {
        module: ['a_critical']
      }
    };

const output = Object.entries(receiver)
  .reduce((a, [user, { module }]) => {
    module.forEach((name) => {
      if (!a[name]) {
        a[name] = { user: [] };
      }
      a[name].user.push(user);
    });
    return a;
  }, {});
console.log(output);

如果您愿意,还可以提前创建累加器对象,因为您拥有allModules,从而避免了.reduce内部的条件:

const receiver =  {
      USER1: {
        module: ['a_critical', 'a_normal','b_normal']
      },
      USER2: {
        module: ['a_critical', 'a_normal','b_critical']
      }, 
      USER3: {
        module: ['a_critical']
      }
    };

const allModules = ['a_normal', 'a_critical', 'b_normal', 'b_critical']; 
const accum = Object.fromEntries(
  allModules.map(
    name => [name, { user: [] }]
  )
);

const output = Object.entries(receiver)
  .reduce((a, [user, { module }]) => {
    module.forEach((name) => {
      a[name].user.push(user);
    });
    return a;
  }, accum);
console.log(output);

答案 1 :(得分:1)

  

使用Array.prototype.reduce()

const receiver = {
   USER1: {
     module: ['a_critical', 'a_normal','b_normal']
   },
   USER2: {
     module: ['a_critical', 'a_normal','b_critical']
   }, 
   USER3: {
     module: ['a_critical']
   }
}

const allModules = ['a_normal', 'a_critical', 'b_normal', 'b_critical']
 

const result = allModules.reduce((modulesObj, moduleName) => {
  modulesObj[moduleName] = [{ user: [] }]
  
  for (let user in receiver) {
    if (receiver[user].module.includes(moduleName)) {
      modulesObj[moduleName][0].user.push(user)
    }
  }
  
  return modulesObj
}, {})


console.log(result)

答案 2 :(得分:0)

尝试这个

const receiver =  {
      USER1: {
        module: ['a_critical', 'a_normal','b_normal']
      },
      USER2: {
        module: ['a_critical', 'a_normal','b_critical']
      }, 
      USER3: {
        module: ['a_critical']
      }
};

const userByModules = Object.keys(receiver).reduce(function (acc, user) {
	receiver[user].module.forEach((module) => {
		if (acc[module]) {
          acc[module].user.push(user);
        } else {
          acc[module] = {user: [user]};
        }
	});
    return acc;
}, {});

console.log(userByModules);

答案 3 :(得分:0)

const receiver = {
  USER1: {
    module: ["a_critical", "a_normal", "b_normal"]
  },
  USER2: {
    module: ["a_critical", "a_normal", "b_critical"]
  },
  USER3: {
    module: ["a_critical"]
  }
};

const allModules = ["a_normal", "a_critical", "b_normal", "b_critical"];

let reduce = () => {
  // create output object
  let output = {};

  // add modules into output
  allModules.map(mod => {
    return (output[mod] = [{ 'user': []}]);
  });

  // map users to modules
  for (let userKey in receiver) {
    let userModules = receiver[userKey].module;
    userModules.forEach(mod => {
      if(output.hasOwnProperty(mod)) {
        output[mod][0]['user'].push(userKey);
      }
    });
  }
};

reduce();

直接完成工作的方式。没有花哨的功能。希望这种逻辑很容易遵循。

答案 4 :(得分:0)

下面的代码片段将提供的allModules数组简化为预期的结果。但是,我认为这种结构

"a_normal": {
      "user": [
        "USER1",
        "USER2"
      ]
 },
...

比以下代码段更具意义,因为您必须访问每个模块的第一个索引以获得user

"a_normal": [
    {
      "user": [
        "USER1",
        "USER2"
      ]
    }
  ],

const receiver = {
  USER1: {  module: ["a_critical", "a_normal", "b_normal"] },
  USER2: { module: ["a_critical", "a_normal", "b_critical"] },
  USER3: {  module: ["a_critical"] }
};
const allModules = ["a_normal", "a_critical", "b_normal", "b_critical"]; 
const result = allModules.reduce((prevResult, curModule, index) => {
  if(!prevResult[curModule]) {
    prevResult[curModule]=[{user:[]}];
  }

  Object.keys(receiver).forEach((user) => {
    if(receiver[user].module.includes(curModule) &&
      !prevResult[curModule][0].user.includes(user)) {
        prevResult[curModule][0].user.push(user);
    }
  });

  return prevResult;
},{});
console.log(JSON.stringify(result, null, 2));