我想转换这样的对象:
foo = {
42: 'foo',
'a.b.c[0].42': 'bar',
'a.b.c[0].43': 'zet',
'a.d.c[0].42': 'baz'
}
要:
bar = {
42: 'foo',
'a.b.c[0].42': 'bar',
'a.b.c[0].43': 'zet',
'a.d.c[0].42': 'baz',
a: {
b: {
c: [{
42: 'bar', 43: 'zet'
}]
},
d: {
c: [{
42: 'baz'
}]
}
}
}
有人知道如何实现convertToTree
功能吗?
我们在项目中使用lodash
,这样可以帮助完成基本操作。
var object = {
42: "foo",
"a.b.c[0].42": "bar",
"a.b.c[0].43": "zet",
"a.d.c[0].42": "baz"
};
function convertToTree() {
// code here
}
convertToTree(object) === {
"42": "foo",
"a.b.c[0].42": "bar",
"a.b.c[0].43": "zet",
"a.d.c[0].42": "baz",
"a": {
"b": {
"c": [
{
"42": "bar",
"43": "zet"
}
]
},
"d": {
"c": [
{
"42": "baz"
}
]
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
UPD:
我需要在另一个代码处进行此类操作的转换:
_.result(bar, 'a.b.c[0].42') === 'bar'
您可以找到_.result
功能说明here。
答案 0 :(得分:1)
您需要为数字索引使用自定义函数,因为lodash将所有数字和数字视为字符串作为数字。它产生稀疏元素,这里不需要它。
function setValue(object, path, value) {
var last = path.pop();
path.reduce(function (o, k, i, kk) {
return o[k] = o[k] || (typeof (i + 1 in kk ? kk[i + 1] : last) === 'number' ? [] : {});
}, object)[last] = value;
}
var foo = { 42: 'foo', 'a.b.c[0].42': 'bar', 'a.b.c[0].43': 'zet', 'a.d.c[0].42': 'baz' },
bar = {};
Object.keys(foo).forEach(function (k) {
setValue(bar, k.split(/\.|(?=\[)/).map(function (v) { return v.match(/^\[.+\]$/) ? +v.slice(1, -1) : v; }), foo[k]);
});
console.log(bar);
.as-console-wrapper { max-height: 100% !important; top: 0; }
与lodash比较
var foo = { 42: 'foo', 'a.b.c[0].42': 'bar', 'a.b.c[0].43': 'zet', 'a.d.c[0].42': 'baz' },
keys = Object.keys(foo),
bar = _.zipObjectDeep(keys, keys.map(function (k) { return foo[k]; }));
console.log(bar);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
答案 1 :(得分:1)
这是一个很小的库:https://github.com/richie5um/flattenjs
console.log(flattened); // { // 'a': true, // 'b.bb[0]': 0, // 'b.bb[1]': 1, // 'b.bb[2]': 2, // 'b.bb[3]': 3, // 'b.bb[4]': 4 // } unflattened = FlattenJS.undo(flattened); console.log(unflattened); // { a: true, b: { bb: [ 0, 1, 2, 3, 4 ] } }
答案 2 :(得分:0)
我的解决方案基于@ mik01aj答案。
var rawObject = {
42: "foo",
"a.b.c[0].42": "bar",
"a.b.c[0].43": "zet",
"a.d.c[0].42": "baz"
};
function convertToTree(rowObjectData) {
return _.assign(
{},
rowObjectData,
_.reduce(rowObjectData, function (result, value, key) {
return _.set(result, key, value);
}, {}))
}
var convertedObject = convertToTree(rawObject);
console.log(_.result(convertedObject, "a.b.c[0].42") === "bar");
console.log(convertedObject["a.b.c[0].42"] === "bar");
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>