从 POJO 生成嵌套集模型
Generating a Nested Set Model from a POJO
我一直在研究一些嵌套集模型 (NSM)。我想做的一件事是能够从给定的 JavaScript 对象生成 NSM。
例如,给定以下对象:
var data = {
Clothes: {
Jackets: {
Waterproof: true,
Insulated: true
},
Hats: true,
Socks: true
},
}
我想像这样生成一个对象数组。
[
{
"name": "Clothes",
"lft": 1,
"rgt": 12
},
{
"name": "Jackets",
"lft": 2,
"rgt": 7
},
{
"name": "Waterproof",
"lft": 3,
"rgt": 4
},
{
"name": "Insulated",
"lft": 5,
"rgt": 6
},
{
"name": "Hats",
"lft": 8,
"rgt": 9
},
{
"name": "Socks",
"lft": 10,
"rgt": 11
}
]
即 - 深度首先遍历对象,为层次结构中的每个对象分配一个 ID 并计算左右边缘。这样每个节点都有一个唯一的 ID 以及 NSM 的正确 lft
和 rgt
值。
我尝试了各种方法,但似乎无法获得我想要的结果...我通过更改模型以使用节点名称和子节点的属性取得了一些成功 - 即
var data2 = {
name: "Clothes",
children: [{
name: "Jackets",
children: [{
name: "Waterproof",
}, {
name: "Insulated"
}]
}, {
name: "Hats"
},
{
name: "Socks"
}
]
};
function nestedSet(o, c, l = 0) {
let n = {
name: o.name,
lft: l + 1
};
c.push(n);
let r = n.lft;
for (var x in o.children) {
r = nestedSet(o.children[x], c, r);
}
n.rgt = r + 1;
return n.rgt;
}
let out = [];
nestedSet(data2, out);
console.log(out)
这给出了正确的结果,但需要更改输入数据...有没有办法使用原始 data
对象生成相同的嵌套集模型?
最后居然解决了这个问题。。。只是忘记了好久!基本上,所需要的只是按照@CherryDT 评论中的善意建议隐蔽地传递 Object.entries
。这样就可以解决 name/children 以根据需要构建嵌套集模型。
var data = {
Clothes: {
Jackets: {
Waterproof: {},
Insulated: {},
},
Hats: {},
Socks: {},
},
};
function ns(node, stack = [], lft = 0) {
var rgt = ++lft;
var item = {
name: node[0],
lft: lft,
};
stack.push(item);
Object.entries(node[1]).forEach(function (c) {
rgt = ns(c, stack, rgt);
});
item.rgt = ++rgt;
return rgt;
}
var result = [];
ns(Object.entries(data)[0], result);
console.log(result);
我一直在研究一些嵌套集模型 (NSM)。我想做的一件事是能够从给定的 JavaScript 对象生成 NSM。
例如,给定以下对象:
var data = {
Clothes: {
Jackets: {
Waterproof: true,
Insulated: true
},
Hats: true,
Socks: true
},
}
我想像这样生成一个对象数组。
[
{
"name": "Clothes",
"lft": 1,
"rgt": 12
},
{
"name": "Jackets",
"lft": 2,
"rgt": 7
},
{
"name": "Waterproof",
"lft": 3,
"rgt": 4
},
{
"name": "Insulated",
"lft": 5,
"rgt": 6
},
{
"name": "Hats",
"lft": 8,
"rgt": 9
},
{
"name": "Socks",
"lft": 10,
"rgt": 11
}
]
即 - 深度首先遍历对象,为层次结构中的每个对象分配一个 ID 并计算左右边缘。这样每个节点都有一个唯一的 ID 以及 NSM 的正确 lft
和 rgt
值。
我尝试了各种方法,但似乎无法获得我想要的结果...我通过更改模型以使用节点名称和子节点的属性取得了一些成功 - 即
var data2 = {
name: "Clothes",
children: [{
name: "Jackets",
children: [{
name: "Waterproof",
}, {
name: "Insulated"
}]
}, {
name: "Hats"
},
{
name: "Socks"
}
]
};
function nestedSet(o, c, l = 0) {
let n = {
name: o.name,
lft: l + 1
};
c.push(n);
let r = n.lft;
for (var x in o.children) {
r = nestedSet(o.children[x], c, r);
}
n.rgt = r + 1;
return n.rgt;
}
let out = [];
nestedSet(data2, out);
console.log(out)
这给出了正确的结果,但需要更改输入数据...有没有办法使用原始 data
对象生成相同的嵌套集模型?
最后居然解决了这个问题。。。只是忘记了好久!基本上,所需要的只是按照@CherryDT 评论中的善意建议隐蔽地传递 Object.entries
。这样就可以解决 name/children 以根据需要构建嵌套集模型。
var data = {
Clothes: {
Jackets: {
Waterproof: {},
Insulated: {},
},
Hats: {},
Socks: {},
},
};
function ns(node, stack = [], lft = 0) {
var rgt = ++lft;
var item = {
name: node[0],
lft: lft,
};
stack.push(item);
Object.entries(node[1]).forEach(function (c) {
rgt = ns(c, stack, rgt);
});
item.rgt = ++rgt;
return rgt;
}
var result = [];
ns(Object.entries(data)[0], result);
console.log(result);