2017-02-27 174 views
2

我試圖做一個簡單的ACL只是爲了實踐。JavaScript - 通過對象遞歸循環

我想通過我的對象數據循環,如果我currentViewer有一個父母我想添加他的路徑(訪問我的對象)arrayAccess。

所以,如果我的瀏覽器是用戶自己accessArray應該["", home],如果他管理這將是["", home, user],如果他是一個客人將是唯一[""]

如何以遞歸的方式做到這一點,所以我不必創建數千個for循環?

我試圖在我的checkParent()裏面調用checkParent(),但這隻會讓我的循環不定。我很抱歉,如果這是一個愚蠢的問題,我在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();

回答

1

你可以試試這個:

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 
+0

謝謝你,但你的陣列管理員只返回'[ 「家」, 「用戶」]'而不是'[ 「」, 「家」, 「用戶」]' – Sara

+0

@Sara:我的不好,請檢查我的最新答案。它現在可以正常工作 –

1

還有一堆的方式來做到這一點。簡單的方法是製作一個哈希以便輕鬆查找並在循環和推送中引用父母。

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"));

1

我不認爲「遞歸」應該是對自己的一個目標......爲什麼不創建一個地圖的角色和他們的屬性,並使用parent屬性從這張地圖中檢索一個新項目,直到你不能?

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"))

0

第一構建對象模型,那麼問題是簡單的。

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);