使用虚拟对象从另一个对象数组创建对象数组



我想从另一个对象数组创建一个对象数组来绘制图形。

这是我用来将对象位置放置在预期对象内的数组。

let uniqueSkills = ['Using', 'Analyzing', 'Summarizing', 'Inferring', 'Predicting', 'Activating']

这是我拥有需要修改的对象。

let data = {
data0:[
{count: 1, length: 1, skill: "Activating"},
{count: 4, length: 1, skill: "Using"},
{count: 2, length: 1, skill: "Analyzing"}
],
data1: [
{count: 2, length: 1, skill: "Summarizing"}
],
data2: [
{count: 1, length: 1, skill: "Predicting"},
{count: 4, length: 1, skill: "Analyzing"}
]
}

最终结果对象应如下所示。

data = {
data0:[
{count: 4, length: 1, skill: "Using"},
{count: 2, length: 1, skill: "Analyzing"},
{skill: "Summarizing"},
{skill: "Inferring"},
{skill: "Predicting"},
{count: 4, length: 1, skill: "Activating"}
],
data1: [
{skill: "Using"},
{skill: "Analyzing"},
{count: 2, length: 1, skill: "Summarizing"},
{skill: "Inferring"},
{skill: "Predicting"},
{skill: "Activating"}
],
data2: [
{skill: "Using"},
{count: 4, length: 1, skill: "Analyzing"},
{skill: "Summarizing"},
{skill: "Inferring"},
{count: 1, length: 1, skill: "Predicting"},
{skill: "Activating"}
]
}

我编写的算法在某些情况下工作正常,但在某些情况下会中断。在这里

Object.keys(data).forEach(key => {      
for (let i = 0; i < uniqueSkills.length; i++) {       
if (typeof data[key][i] == 'object') {      
if (data[key][i].skill !== uniqueSkills[i]) {     
let index = uniqueSkills.indexOf(data[key][i].skill)
if (typeof data[key][index] == 'object') {
let anotherIndex = uniqueSkills.indexOf(data[key][index].skill)
let elementAtIndex = data[key][index]
let elementAtAnotherIndex = data[key][anotherIndex]
data[key][i] = elementAtIndex
data[key][index] = elementAtAnotherIndex
}
else {
data[key][index] = data[key][i]
data[key][i] = {skill: uniqueSkills[i]}
}
}
} else {        
data[key][i] = {skill: uniqueSkills[i]}       
}       
}     
})

您可以使用Map首先创建像空模板一样,对象中只有skill属性,然后用您拥有的实际数据填充该MapObject.entriesObject.fromEntries可用于从普通对象转换为数组,反之亦然。

由于Map保留了广告顺序,因此输出顺序将得到保证。

let uniqueSkills = ['Using', 'Analyzing', 'Summarizing', 'Inferring', 'Predicting', 'Activating']
let data = {data0:[{count: 1, length: 1, skill: "Activating"},{count: 4, length: 1, skill: "Using"},{count: 2, length: 1, skill: "Analyzing"}],data1: [{count: 2, length: 1, skill: "Summarizing"}],data2: [{count: 1, length: 1, skill: "Predicting"},{count: 4, length: 1, skill: "Analyzing"}]};
let newData = Object.fromEntries(Object.entries(data).map(([k, arr]) =>
[k, Array.from(arr.reduce(
(map, o) => map.set(o.skill, o),
new Map(uniqueSkills.map(skill => [skill, { skill }]))
).values())]
));
console.log(newData);

请注意,此解决方案具有最坏情况O(n²(时间复杂度(就uniqueSkills的长度而言(。你自己的解决方案的时间复杂度为O(n³(,有两个外循环(forEachfor(和嵌套的indexOf调用,这也表示一个循环。其他解,而不是indexOf,有一个嵌套的findfindIndex,也有O(n³(的时间复杂度。使用Map#get而不是这些数组方法之一,将复杂性降低到O(n²(。

此解决方案不会改变原始data对象。它生成一个新对象。但是,新对象仍将包括在原始data数组中找到的原始对象。

你的解决方案的问题在于你走一条iindexanotherIndex的路径,试图移动一个阻碍你想要插入的对象的对象。但这条路可能比这更长。这种创造差距的"行走",移动到下一个位置,在那里创造差距,......等,是先验的,不受长度限制。

对于数据中的每个对象,调用Array.prototype.mapforuniqueSkills并查找对象。 如果找到,则返回对象,如果没有,则返回一个新对象。

并将数组替换为原点。

let uniqueSkills = ['Using', 'Analyzing', 'Summarizing', 'Inferring', 'Predicting', 'Activating']
let data = {data0:[{count: 1, length: 1, skill: "Activating"},{count: 4, length: 1, skill: "Using"},{count: 2, length: 1, skill: "Analyzing"}],data1: [{count: 2, length: 1, skill: "Summarizing"}],data2: [{count: 1, length: 1, skill: "Predicting"},{count: 4, length: 1, skill: "Analyzing"}]};
Object.keys(data).forEach(key => {
data[key] =
uniqueSkills.map(skill => data[key].find(e => e.skill === skill) || { skill });
});
console.log(data);

最新更新