我在这里处理两个主要对象。一个叫做tasks
,它是一个对象数组。另一个名为userSelectedRoles
,它是角色ID的数组。
在我的tasks数组中,有一个名为Roles
的属性,它也是一个对象数组。
我正在尝试查看任何任务中是否存在userSelectedRoles
,如果没有,请将其添加到任务中。
我创造了一些伪装,我试图绕过它。
示例:
var userSelectedRoles = [1, 2, 3],
tasks = [{
TaskName: 'Task 1',
TaskID: 1,
Roles: [{
RoleName: 'Role1',
RoleID: 1
}, {
RoleName: 'Role 2',
RoleID: 2
}]
}, {
TaskName: 'Task 2',
TaskID: 2,
Roles: [{
RoleName: 'Role1',
RoleID: 1
}, {
RoleName: 'Role 3',
RoleID: 3
}]
}]
// Loop over our tasks
for (var t = 0; t < tasks.length; t++) {
// Loop over the roles
for (var r = 0; r < tasks[t].Roles.length; r++) {
// Loop over our user selected roles
for (var sr = 0; sr < userSelectedRoles.length; sr++) {
// If this user selected role exists within our roles, continue
if (tasks[t].Roles[r].RoleID == userSelectedRoles[sr]) {
// This role exists, no need to do anything
} else {
// This user selected role does not exist in our tasks, we need to add it
tasks[t].Roles.push({
RoleName: 'Blah',
RoleID: userSelectedRoles[sr]
})
}
}
}
}
上面的代码无法正常工作,我的小提琴撞坏了,所以我假设某个地方出现了循环错误。
有没有更容易的方法来做到这一点,而不必做所有的循环?
这里的最终目标是在两个任务中添加一个新角色。 Task 1 = Role 3
&amp; Task 2 = Role 2
。
思想?
答案 0 :(得分:0)
您可以使用哈希表并收集ID。然后迭代userSelectedRoles
,如果没有设置,则将对象推送到Roles
。
var userSelectedRoles = [1, 2, 3],
tasks = [{ TaskName: 'Task 1', TaskID: 1, Roles: [{ RoleName: 'Role1', RoleID: 1 }, { RoleName: 'Role 2', RoleID: 2 }] }, { TaskName: 'Task 2', TaskID: 2, Roles: [{ RoleName: 'Role1', RoleID: 1 }, { RoleName: 'Role 3', RoleID: 3 }] }];
tasks.forEach(function (task) {
var roleIds = Object.create(null);
task.Roles.forEach(function (role) {
roleIds[role.RoleID] = true;
});
userSelectedRoles.forEach(function (id) {
if (!roleIds[id]) {
task.Roles.push({ RoleName: 'Blah', RoleID: id });
}
});
});
console.log(tasks);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
ES6与Set
var userSelectedRoles = [1, 2, 3],
tasks = [{ TaskName: 'Task 1', TaskID: 1, Roles: [{ RoleName: 'Role1', RoleID: 1 }, { RoleName: 'Role 2', RoleID: 2 }] }, { TaskName: 'Task 2', TaskID: 2, Roles: [{ RoleName: 'Role1', RoleID: 1 }, { RoleName: 'Role 3', RoleID: 3 }] }];
tasks.forEach(function (task) {
var ids = new Set(task.Roles.map(({ RoleID }) => RoleID));
userSelectedRoles.forEach(id => ids.has(id) || task.Roles.push({ RoleName: 'Blah', RoleID: id }));
});
console.log(tasks);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
答案 1 :(得分:0)
这样做怎么样? (我总是讨厌使用for循环,添加我们不需要的其他变量,即索引)
tasks.forEach(task => {
var roleIds = task.Roles.map(r=>r.RoleID);
userSelectedRoles.forEach( r => {
if(roleIds.indexOf(r) === -1){
task.Roles.push({RoleID: r, RoleName: 'blah'})
}
})
})
答案 2 :(得分:0)
如果您想知道错误的位置...在最后一个循环中,您将向角色添加项目。这意味着1级以上的循环现在将再循环1次。而这个循环将添加一个新角色,这将使它再循环一次,这将增加一个角色 - 我认为你现在得到它了:)
使用相同结构的解决方案:在开始循环之前将长度存储在变量中,并将其用于循环次数。
for (var t = 0; t < tasks.length; t++) {
//CHANGED CODE START
let rolesLength = task[t].Roles.length;
// Loop over the roles
for (var r = 0; r < rolesLength ; r++) {
//CHANGED CODE END
// Loop over our user selected roles
for (var sr = 0; sr < userSelectedRoles.length; sr++) {
// If this user selected role exists within our roles, continue
if (tasks[t].Roles[r].RoleID == userSelectedRoles[sr]) {
// This role exists, no need to do anything
} else {
// This user selected role does not exist in our tasks, we need to add it
tasks[t].Roles.push({
RoleName: 'Blah',
RoleID: userSelectedRoles[sr]
})
}
}
}
}