Javascript - 将嵌套对象转换为项目数组
Javascript - Convert Nested Object to Array of items
我有一个看起来像这样的对象:
[
{
"id": 1,
"name": "Electronics",
"path": "Electronics",
"children": [
{
"id": 2,
"name": "Laptops & PC",
"path": "Electronics > Laptops & PC",
"children": []
},
{
"id": 7,
"name": "Phones & Accessories",
"path": "Electronics > Phones & Accessories",
"children": [
{
"id": 8,
"name": "Smartphones",
"path": "Electronics > Phones & Accessories > Smartphones",
"children": [
{
"id": 9,
"name": "Android",
"path": "Electronics > Phones & Accessories > Smartphones > Android",
"children": []
},
{
"id": 10,
"name": "iOS",
"path": "Electronics > Phones & Accessories > Smartphones > iOS",
"children": []
}
]
}
]
}
]
},
{
"id": 11,
"name": "Software",
"path": "Software",
"children": []
}
]
我想把它转换成这样:
[
{header: 'Electronics'},
{name: 'Laptops & PC', group: 'Electronics', id: 2},
{name: 'Phones & Accessories', group: 'Electronics', id: 7},
{name: 'Smartphones', group: 'Phones & Accessories', id: 8},
{name: 'Android', group: 'Smartphones', id: 9},
{name: 'iOS', group: 'Smartphones', id: 10},
{divider: true},
{name: 'Software', group: 'Software', id: 11}
]
基本上,
- 如果根元素有子元素,则应将其转换为
header
。
- 所有元素的父名称都应为
group
- 完成一个根元素后,需要插入
{divider: true}
才能继续下一个。 (如果是最后一个根元素,不要插入{divider: true}
虽然我能够在 Whosebug 上找到很多从层次结构到 JSON 的解决方案,但我无法对这些解决方案进行逆向工程。
有人可以帮我吗?
您可以通过检查 header 保持相应的分隔符并迭代 children.
来采用迭代和递归方法
然后您需要为任何项目添加标准 object。
递归回调对组使用闭包。如果未设置,则该组是根项。
function getParts(array) {
var result = [];
array.forEach(function iter(group) {
return function ({ id, name, children }, i, { length }) {
if (!group && children.length) {
result.push({ header: name });
}
if (group || !children.length) {
result.push({ name, group: group || name, id });
}
children.forEach(iter(name));
if (!group && i + 1 !== length) {
result.push({ divider: true });
}
};
}(''));
return result;
}
var data = [{ id: 1, name: "Electronics", path: "Electronics", children: [{ id: 2, name: "Laptops & PC", path: "Electronics > Laptops & PC", children: [] }, { id: 7, name: "Phones & Accessories", path: "Electronics > Phones & Accessories", children: [{ id: 8, name: "Smartphones", path: "Electronics > Phones & Accessories > Smartphones", children: [{ id: 9, name: "Android", path: "Electronics > Phones & Accessories > Smartphones > Android", children: [] }, { id: 10, name: "iOS", path: "Electronics > Phones & Accessories > Smartphones > iOS", children: [] }] }] }] }, { id: 11, name: "Software", path: "Software", children: [] }, { id: 11, name: "Software", path: "Software", children: [] }, { id: 11, name: "Software", path: "Software", children: [] }],
result = getParts(data);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
这是一种递归方法,使用 array.reduce
和扩展运算符 (...
) 在您移动数据时展平列表,还有一个单独的辅助函数来处理 non-headers :
const flatten = data =>
data.reduce((a, e, i) => {
if (e.children.length) {
a.push({header: e.name});
a.push(...flattenR(e.children, e.name));
}
else {
a.push({name: e.name, group: e.name, id: e.id});
}
if (i < data.length - 1) {
a.push({divider: true});
}
return a;
}, [])
;
const flattenR = (data, grp) =>
data.reduce((a, e) => {
a.push({name: e.name, group: grp, id: e.id});
a.push(...flattenR(e.children, e.name));
return a;
}, [])
;
const data = [
{
"id": 1,
"name": "Electronics",
"path": "Electronics",
"children": [
{
"id": 2,
"name": "Laptops & PC",
"path": "Electronics > Laptops & PC",
"children": []
},
{
"id": 7,
"name": "Phones & Accessories",
"path": "Electronics > Phones & Accessories",
"children": [
{
"id": 8,
"name": "Smartphones",
"path": "Electronics > Phones & Accessories > Smartphones",
"children": [
{
"id": 9,
"name": "Android",
"path": "Electronics > Phones & Accessories > Smartphones > Android",
"children": []
},
{
"id": 10,
"name": "iOS",
"path": "Electronics > Phones & Accessories > Smartphones > iOS",
"children": []
}
]
}
]
}
]
},
{
"id": 11,
"name": "Software",
"path": "Software",
"children": []
}
];
console.log(flatten(data));
我有一个看起来像这样的对象:
[
{
"id": 1,
"name": "Electronics",
"path": "Electronics",
"children": [
{
"id": 2,
"name": "Laptops & PC",
"path": "Electronics > Laptops & PC",
"children": []
},
{
"id": 7,
"name": "Phones & Accessories",
"path": "Electronics > Phones & Accessories",
"children": [
{
"id": 8,
"name": "Smartphones",
"path": "Electronics > Phones & Accessories > Smartphones",
"children": [
{
"id": 9,
"name": "Android",
"path": "Electronics > Phones & Accessories > Smartphones > Android",
"children": []
},
{
"id": 10,
"name": "iOS",
"path": "Electronics > Phones & Accessories > Smartphones > iOS",
"children": []
}
]
}
]
}
]
},
{
"id": 11,
"name": "Software",
"path": "Software",
"children": []
}
]
我想把它转换成这样:
[
{header: 'Electronics'},
{name: 'Laptops & PC', group: 'Electronics', id: 2},
{name: 'Phones & Accessories', group: 'Electronics', id: 7},
{name: 'Smartphones', group: 'Phones & Accessories', id: 8},
{name: 'Android', group: 'Smartphones', id: 9},
{name: 'iOS', group: 'Smartphones', id: 10},
{divider: true},
{name: 'Software', group: 'Software', id: 11}
]
基本上,
- 如果根元素有子元素,则应将其转换为
header
。 - 所有元素的父名称都应为
group
- 完成一个根元素后,需要插入
{divider: true}
才能继续下一个。 (如果是最后一个根元素,不要插入{divider: true}
虽然我能够在 Whosebug 上找到很多从层次结构到 JSON 的解决方案,但我无法对这些解决方案进行逆向工程。
有人可以帮我吗?
您可以通过检查 header 保持相应的分隔符并迭代 children.
来采用迭代和递归方法然后您需要为任何项目添加标准 object。
递归回调对组使用闭包。如果未设置,则该组是根项。
function getParts(array) {
var result = [];
array.forEach(function iter(group) {
return function ({ id, name, children }, i, { length }) {
if (!group && children.length) {
result.push({ header: name });
}
if (group || !children.length) {
result.push({ name, group: group || name, id });
}
children.forEach(iter(name));
if (!group && i + 1 !== length) {
result.push({ divider: true });
}
};
}(''));
return result;
}
var data = [{ id: 1, name: "Electronics", path: "Electronics", children: [{ id: 2, name: "Laptops & PC", path: "Electronics > Laptops & PC", children: [] }, { id: 7, name: "Phones & Accessories", path: "Electronics > Phones & Accessories", children: [{ id: 8, name: "Smartphones", path: "Electronics > Phones & Accessories > Smartphones", children: [{ id: 9, name: "Android", path: "Electronics > Phones & Accessories > Smartphones > Android", children: [] }, { id: 10, name: "iOS", path: "Electronics > Phones & Accessories > Smartphones > iOS", children: [] }] }] }] }, { id: 11, name: "Software", path: "Software", children: [] }, { id: 11, name: "Software", path: "Software", children: [] }, { id: 11, name: "Software", path: "Software", children: [] }],
result = getParts(data);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
这是一种递归方法,使用 array.reduce
和扩展运算符 (...
) 在您移动数据时展平列表,还有一个单独的辅助函数来处理 non-headers :
const flatten = data =>
data.reduce((a, e, i) => {
if (e.children.length) {
a.push({header: e.name});
a.push(...flattenR(e.children, e.name));
}
else {
a.push({name: e.name, group: e.name, id: e.id});
}
if (i < data.length - 1) {
a.push({divider: true});
}
return a;
}, [])
;
const flattenR = (data, grp) =>
data.reduce((a, e) => {
a.push({name: e.name, group: grp, id: e.id});
a.push(...flattenR(e.children, e.name));
return a;
}, [])
;
const data = [
{
"id": 1,
"name": "Electronics",
"path": "Electronics",
"children": [
{
"id": 2,
"name": "Laptops & PC",
"path": "Electronics > Laptops & PC",
"children": []
},
{
"id": 7,
"name": "Phones & Accessories",
"path": "Electronics > Phones & Accessories",
"children": [
{
"id": 8,
"name": "Smartphones",
"path": "Electronics > Phones & Accessories > Smartphones",
"children": [
{
"id": 9,
"name": "Android",
"path": "Electronics > Phones & Accessories > Smartphones > Android",
"children": []
},
{
"id": 10,
"name": "iOS",
"path": "Electronics > Phones & Accessories > Smartphones > iOS",
"children": []
}
]
}
]
}
]
},
{
"id": 11,
"name": "Software",
"path": "Software",
"children": []
}
];
console.log(flatten(data));