我一直试图创建一个树结构,如下:
var result = {
email: {
schema: {
verified: 'email.verified',
email_address: 'email.email_address',
entity: {
schema: {
name: 'email.entity.name',
type: 'email.entity.type',
email: {
schema: {
verified: 'email.entity.email.verified',
email_address: 'email.entity.email.email_address'
}
}
}
}
}
}
};
根据下面给出的数组数据:
var schema = {
'paths': [
'email.email_address',
'email.entity.email.email_address',
'email.entity.email.verified',
'email.entity.type',
'email.entity.name',
'email.verified',
'created_at',
'contact_numbers'
]
}
您看到我期望的输出具有schema
级嵌套的n
属性,这是不可预测的。就像paths
一样,它取决于'email.entity.email.email_address'
的值。您可以用点将其拆分,并且看起来每个点在输出中都被schema
属性替换。
我正在尝试使用递归,但是我无法设置该流程。下面是到目前为止我尝试过的代码:
var schema = {
'paths': [
'email.email_address',
'email.entity.email.email_address',
'email.entity.email.verified',
'email.entity.type',
'email.entity.name',
'email.verified',
'created_at',
'contact_numbers'
]
}
var newSchema = {};
var key = 'email';
var existKeys = schema.paths.filter((path) => path.includes(key + '.'));
var requiredObject = {};
existKeys.forEach((existKey) => {
var splitKeys = existKey.split('.');
splitKeys.forEach((splitKey, index) => {
if (requiredObject[splitKey] && index + 1 === splitKeys.length) {
requiredObject[splitKey].schema = existKey;
} else {
requiredObject[splitKey] = {
'schema': {}
}
}
});
});
console.log(requiredObject);
答案 0 :(得分:1)
您可以减少路径,并为每个找到的键都设置一个schema
属性。
var schema = { paths: ['email.email_address', 'email.entity.email.email_address', 'email.entity.email.verified', 'email.entity.type', 'email.entity.name', 'email.verified', 'created_at', 'contact_numbers'] },
result = schema.paths
.filter(s => s.startsWith('email')) // or not or so, if so, maybe
.reduce((r, p) => {
var keys = p.split('.'),
last = keys.pop();
keys.reduce((o, k) => (o[k] = o[k] || { schema: {} }).schema, r)[last] = p;
return r;
}, {});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 1 :(得分:0)
我使用辅助函数reduce
在paths
数组上assignNested
,给定一个外部对象,一个值和一个属性数组,该函数使用top属性创建schema
对象并递归调用自身,直到数组只剩下一项,并且可以分配最终值:
var schema = {
'paths': [
'email.email_address',
'email.entity.email.email_address',
'email.entity.email.verified',
'email.entity.type',
'email.entity.name',
'email.verified',
'created_at',
'contact_numbers'
]
};
function assignNested(obj, val, props) {
if (props.length === 1) {
obj[props[0]] = val;
return;
}
const nextProp = props.shift();
if (!obj.schema) obj.schema = {};
if (!obj.schema[nextProp]) obj.schema[nextProp] = {};
assignNested(obj.schema[nextProp], val, props);
}
const fullResult = schema.paths.reduce((a, path) => {
const props = path.split('.');
assignNested(a, path, props);
return a;
}, {});
// fullResult contains the *full* structure,
// but if you only want the nested `email` part, then:
const result = {
email: {
schema: fullResult.schema.email
}
};
console.log(result);
答案 2 :(得分:0)
使用2 Array.reduce
可以实现以下效果
var schema = {
'paths': [
'email.email_address',
'email.entity.email.email_address',
'email.entity.email.verified',
'email.entity.type',
'email.entity.name',
'email.verified',
'created_at',
'contact_numbers'
]
}
let res = schema.paths.reduce((o, d) => {
let keys = d.split('.')
keys.reduce((t, k, i) => {
t[k] = (i != keys.length - 1)
? (t[k] || { schema: {} })
: d
return t[k].schema
}, o)
return o
}, {})
console.log(res)
// for only email
console.log({ email: res.email })