繁体   English   中英

数组的所有元素作为对象中的键

[英]All element of an array as key in an Object

我试图从另一个数组和对象构造一个对象数组。

let assets = [
               {id: '1', count: 1, skills: ["teach", "play"]},
               {id: '2', count: 1, skills: ["write", "surf"]},
               {id: '3', count: 2, skills: ["run"]},
               {id: '4', count: 3, skills: ["teach", "run", "hike"]}
             ]

然后,我将介绍以上所有可用的独特技能。

let uniqueSkills = ["teach", "play", "write", "surf", "run", "hike"]

uniqueSkills数组中的每个元素都必须是对象中的键。 而且,如果该键存在于资产数组中,那么我想存储该特定对象的idcount

我期望我的最终对象是类似这样的东西,我将不得不使用它来绘制图形。

{
  teach: [{id: 1, count: 1},{id: 4, count: 3}],
  play: [{id: 1, count: 1}],
  write: [{id: 2, count: 1}],
  surf: [{id: 2, count: 1}],
  run: [{id: 3, count: 2}, {id: 4, count: 3}],
  hike: [{id: 4, count: 3}]
}

您可以reduce阵列。 解构的参数来获取skillsrest分开的属性。 然后遍历skills并在累加器中添加/更新密钥

 const assets=[{id:'1',count:1,skills:["teach","play"]},{id:'2',count:1,skills:["write","surf"]},{id:'3',count:2,skills:["run"]},{id:'4',count:3,skills:["teach","run","hike"]}] const output = assets.reduce((acc, { skills, ...rest }) => { skills.forEach(s => { acc[s] = acc[s] || []; acc[s].push(rest) }) return acc; }, {}) console.log(output) 

(请检查浏览器的控制台以获取实际输出。代码段显示不正确)

let finalObj = {};
uniqueSkills.map( (skill) => {
  finalObj[skill] = assets.filter( asset => asset.skills.includes(skill) )
  .map( asset => ({id: asset.id, count: asset.count}) );  
})

这有点复杂,所以让我为您分解:

  1. 通过Array.map()遍历所有uniqueSkills。

  2. 对于每个技能,我们都会在最终对象中创建一个属性,其名称为技能。

  3. 过滤资产数组以删除skills属性中不包含该技能的任何对象。

  4. 在从filter返回的数组上,返回仅包含idcount属性的数组,并将该数组放入步骤2中创建的属性中。

有关数组函数的更多信息: Array.map()Array.filter()

希望这可以帮助 :)

这是不使用reduce的解决方案,而是依靠函数生成器,并使用.filter来获取所需的过滤值。

下面的代码将迭代所有独特的技能,并针对每个技能构建一个对象。

它并不意味着效率更高,它只是完成任务的另一种方式,并且具有弹性并且易于维护。 而且,也有可能根本不依赖任何数组原型。

如果需要,下面的方法允许进行进一步的对象转换。

 let assets = [ {id: '1', count: 1, skills: ["teach", "play"]}, {id: '2', count: 1, skills: ["write", "surf"]}, {id: '3', count: 2, skills: ["run"]}, {id: '4', count: 3, skills: ["teach", "run", "hike"]} ]; let uniqueSkills = ["teach", "play", "write", "surf", "run", "hike"]; // Aggregates the source results by looking for uniqueSkills in its skills property. function* aggregateByUniqueSkills(source, uniqueSkills) { // loop each uniques skill. for (var skill of [...new Set(uniqueSkills)]) { // <-- new Set ensures there are no duplicates. const skillSet = {[skill]: []}; // <-- define a new object with a key and a default empty array value. for ({id, count} of source.filter(i => i.skills && i.skills.indexOf(skill) > -1)) { // acquire all the elements in the source whose skills contains the current skill. skillSet[skill].push({id, count}); // push the value. } yield skillSet; // yield the current result. } } console.log(Object.assign({}, ...aggregateByUniqueSkills(assets, uniqueSkills))); 

好吧,没有捷径可做。 只是一个简单的算法。 这是一个有效的解决方案。

 let assets = [ { id: '1', count: 1, skills: ["teach", "play"] }, { id: '2', count: 1, skills: ["write", "surf"] }, { id: '3', count: 2, skills: ["run"] }, { id: '4', count: 3, skills: ["teach", "run", "hike"] } ]; // Filter unique keys into an array let skillKeys = []; assets.forEach(element => { skillKeys = [...new Set(skillKeys.concat(element['skills']))]; }); // Final refined result let refined = {}; let temp = []; skillKeys.forEach(sKey => { temp = []; assets.forEach(a => { if (a['skills'].includes(sKey)) { temp.push({ id: a['id'], count: a['count'] }); } }) refined[sKey] = temp; }); console.log(refined); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM