问题:
I retrieve the following array of string values
[
"Module1.resource1.create",
"Module1.resource1.read",
"Module1.resource1.update",
"Module1.resource1.delete",
...
"Modu...
可以将文章内容翻译成中文,广告屏蔽插件会导致该功能失效:
问题:
I retrieve the following array of string values
[
"Module1.resource1.create",
"Module1.resource1.read",
"Module1.resource1.update",
"Module1.resource1.delete",
...
"Module1.resourceN.create",
"Module1.resourceN.read",
"Module1.resourceN.update",
]
I would like to change them to json format like this
{"privileges": {
"Module1": {
"resource1": {
"create": true,
"read": true,
"update": true,
"delete": true,
},
...
"resourceN": {
"create": true,
"read": true,
"update": true,
}
}
}
}
All I can think of is run a loop for each string, use split(".")
and then somehow change it to json object. the problem I'm having is that the json is not a simple key: value
, it's more of a key: object: object: object: value
if that makes sense ...
I would appreciate the nudge in the right direction.
cheers
回答1:
You can use Array#reduce
method:
const result = { privileges: {} };
items.reduce((ret, el) => {
// Split the array elements and use destructuring assignment syntax for
// creating constants
const [module, resource, verb] = el.split('.');
// check if privileges[module] property exists. If not, define it as an empty object.
if (!ret[module]) ret[module] = {};
// follows the previous line's logic for resources!
if (!ret[module][resource]) ret[module][resource] = {};
ret[module][resource][verb] = true;
return ret;
}, result.privileges);
Demo | Destructuring assignment syntax
回答2:
May be using dot-object will help without reinventing the wheel:
https://github.com/rhalff/dot-object
回答3:
This took a while, but does the job:
const rules = [
"Module1.resource1.create",
"Module1.resource1.read",
"Module1.resource1.update",
"Module1.resource1.delete",
"Module1.resourceN.create",
"Module1.resourceN.read",
"Module1.resourceN.update",
].map(rule => rule.split('.'));
const res = { privileges: {} };
for (const rule of rules) {
for (i = 0; i < rule.length; i++) {
switch (i) {
case 0:
res.privileges[rule[0]] = Object.assign({}, res.privileges[rule[0]])
break;
case 1:
res.privileges[rule[0]][rule[1]] = Object.assign({}, res.privileges[rule[0]][rule[1]])
break;
case 2:
res.privileges[rule[0]][rule[1]][rule[2]] = true
default:
}
}
}
console.log(res)
回答4:
To do that you can use the following function:
function setIn(target, path, value) {
var chain = String(path).split('.');
while (chain.length > 0) {
var field = chain.shift();
if (chain.length == 0) {
target[field] = value;
} else if (field in target && target[field] !== null && typeof target[field] === 'object') {
target = target[field];
} else {
target[field] = {}
target = target[field];
}
}
return value;
}
And produce the tree:
var tree = { privileges: {} };
for (var i = 0; i < array.length; i += 1)
setIn(tree.privileges, array[i], true);
回答5:
You can use Array.reduce()
for this to create your nested map. The above example will work for any level of children and will always set the last child to a boolean value.
const arr = ["Module1.resource1.create","Module1.resource1.read","Module1.resource1.update","Module1.resource1.delete","Module1.resourceN.create","Module1.resourceN.read","Module1.resourceN.update","Module2.resourceN.update",];
let result = {privalages:{}};
result.privalages = arr.reduce((o, curr)=>{
let props = curr.split(".");
props.reduce((a, prop, index)=> a[prop] = index !== props.length-1 ?(a[prop] || {}) : true,o);
return o;
},{});
console.log(result);