Reputation: 339
I'm trying to make a simple ACL just for practice.
I want to loop through my object data and if my currentViewer has a parent I want to add his path (access in my object) to arrayAccess.
So if my viewer is user his accessArray should be ["", home]
, if he's admin it would be ["", home, user]
and if he's a guest it will be only [""]
.
How to do it in a recursive way, so I don't have to create thousands of for loops?
I was trying calling a checkParent()
inside my checkParent()
, but it only makes my loop infinitive. I'm sorry if it's a silly question, I'm very beginning in JS.
var currentViewer = "user";
var data = {
users: [{
role: "guest",
access: ""
},
{
role: "user",
access: "home",
parent: "guest"
},
{
role: "admin",
access: "user",
parent: "user"
}
]
};
var accessArray = [];
function checkRole() {
var users = data.users;
for (var i = 0; i < users.length; i++) {
if (currentViewer === users[i].role) {
accessArray.push(users[i].access);
console.log(accessArray);
function checkParent() {
if (users[i].parent) {
for (var j = 0; j < users.length; j++) {
if (users[i].parent === users[j].role) {
accessArray.push(users[j].access);
console.log(accessArray);
}
}
}
};
checkParent();
}
};
};
checkRole();
Upvotes: 3
Views: 2161
Reputation: 4543
You can try this:
var data = {
users : [
{ role:"guest" , access:"" },
{ role:"user" , access:"home", parent: "guest" },
{ role:"admin" , access:"user", parent: "user" }
]
};
var currentUser = "admin";
var arr = [];//array that you need
var defineAccess = function(item){
if(item.parent){
var index = data.users.map(function(e) { return e.role; }).indexOf(item.parent);
defineAccess(data.users[index]); //recursive calling
arr.push(data.users[index].access);
}
}
data.users.forEach(function(item){
if(currentUser === item.role){
arr.push(item.access);
defineAccess(item);
}
})
console.log(arr); //final output array
Upvotes: 1
Reputation: 30696
build an object model first,then the problem is simple.
var data = {
users: [
{
role: "guest",
access: ""
},
{
role: "user",
access: "home",
parent: "guest"
},
{
role: "admin",
access: "user",
parent: "user"
}
]
};
var users = data.users.reduce(function (roles, user) {
roles[user.role] = user;
return roles;
}, {});
var accessList = data.users.map(function (user) {
var all = [];
do {
all.unshift(user.access);
user = users[user.parent];
} while (user);
return all;
});
console.log(accessList);
Upvotes: 0
Reputation: 23397
I don't think "recursiveness" should be a goal on its own... Why not create a Map of roles and their properties and use the parent
property to retrieve a new item from this map, until you can't?
var data = {
users: [{
role: "guest",
access: ""
},
{
role: "user",
access: "home",
parent: "guest"
},
{
role: "admin",
access: "user",
parent: "user"
}
]
};
var roles = new Map(data.users.map(u => [u.role, u]));
var getAccess = function(role) {
var access = [];
var current = roles.get(role);
while (current) {
access.push(current.access);
current = roles.get(current.parent);
}
return access.reverse();
}
console.log("guest", getAccess("guest"))
console.log("user", getAccess("user"))
console.log("admin", getAccess("admin"))
Upvotes: 1
Reputation: 207557
There are a bunch of ways to do it. Simple way is just make a hash for easy look up and reference the parents on a loop and push.
var data = { users : [
{ role:"guest" , access:"" },
{ role:"user" , access:"home", parent: "guest" },
{ role:"admin" , access:"user", parent: "user" }
]
};
var roleHash = data.users.reduce(function(o, i) {
o[i.role] = i;
return o;
}, {});
function getAccessRoles(roleKey) {
var role = roleHash[roleKey];
var roles = [role.access];
while (role.parent) {
role = roleHash[role.parent];
roles.unshift(role.access);
}
return roles;
}
console.log("admin", getAccessRoles("admin"));
console.log("user", getAccessRoles("user"));
console.log("guest", getAccessRoles("guest"));
Upvotes: 1