使用带递归的 reduce 函数从多级树生成一个平面 id 数组?
Generate a flat array of ids from a multilevel tree using reduce function with recursion?
我正在尝试使用 js 库 orgChart 实现用户层次结构。通过库中的 getHierarchy()
方法输出如下对象。
var datascource = {
"id": "1",
"children": [{
"id": "2"
}, {
"id": "3",
"children": [{
"id": "4"
}, {
"id": "5",
"children": [{
"id": "6"
}, {
"id": "7"
}]
}]
}, {
"id": "10"
}, {
"id": "12"
}]
};
我想从树中的 ID 生成平面数组。
例如://["1", "2", "3", "4", "5", "6", "7", "10", "12"]
我想到了,
function getNestedArraysOfIds(node) {
if (node.children == undefined) {
return [node.id];
} else {
return [node.id,...node.children.map(subnode => (subnode.children==undefined) ? subnode.id: getNestedArraysOfIds(subnode))];
}
}
function getIds(array) {
return array.reduce((acc, subArray) =>
(Array.isArray(subArray)) ? [...acc, ...getIds(subArray)] : [...acc, subArray]);
}
var idArrays = getNestedArraysOfIds(datascource );
var ids = getIds(idArrays); //["1", "2", "3", "4", "5", "6", "7", "10", "12"]
我曾尝试使用单个 reduce 函数来完成它,但我最终写了两个函数,它们都是递归的。有没有很多优雅有效的方法可以用单一的 reduce 函数来做到这一点?
提前谢谢你。
使用 Array.flatMap()
的递归并传播以获得 id 和 children 的 id,然后展平为单个数组:
const getIds = ({ id, children }) => children ? [id, ...children.flatMap(getIds)] : id;
const dataSource = {"id":"1","children":[{"id":"2"},{"id":"3","children":[{"id":"4"},{"id":"5","children":[{"id":"6"},{"id":"7"}]}]},{"id":"10"},{"id":"12"}]};
const result = getIds(dataSource);
console.log(result);
您可以通过使用 concat
进行映射来平整 children。
function getFlat({ id, children = [] }) {
return [id].concat(...children.map(getFlat));
}
var data = { id: "1", children: [{ id: "2" }, { id: "3", children: [{ id: "4" }, { id: "5", children: [{ id: "6" }, { id: "7" }] }] }, { id: "10" }, { id: "12" }] };
console.log(getFlat(data));
与 reduce 函数相同
function getFlat({ id, children = [] }) {
return children.reduce((r, o) => [...r, ...getFlat(o)], [id]);
}
var data = { id: "1", children: [{ id: "2" }, { id: "3", children: [{ id: "4" }, { id: "5", children: [{ id: "6" }, { id: "7" }] }] }, { id: "10" }, { id: "12" }] };
console.log(getFlat(data));
您可以创建一个简单的 recursive
函数并使用 for..in
对其进行迭代。如果键是 id
然后将它的值推送到一个数组,否则如果键的值是一个数组,例如 children
键的值是一个数组,然后调用相同的递归在for循环中运行并传递每个对象
let datascource = {
"id": "1",
"children": [{
"id": "2"
}, {
"id": "3",
"children": [{
"id": "4"
}, {
"id": "5",
"children": [{
"id": "6"
}, {
"id": "7"
}]
}]
}, {
"id": "10"
}, {
"id": "12"
}]
};
let data = [];
function flatData(obj) {
for (let keys in obj) {
if (keys === 'id') {
data.push(obj[keys])
} else if (Array.isArray(obj[keys])) {
obj[keys].forEach((item) => {
flatData(item)
})
}
}
}
flatData(datascource)
console.log(data)
我正在尝试使用 js 库 orgChart 实现用户层次结构。通过库中的 getHierarchy()
方法输出如下对象。
var datascource = {
"id": "1",
"children": [{
"id": "2"
}, {
"id": "3",
"children": [{
"id": "4"
}, {
"id": "5",
"children": [{
"id": "6"
}, {
"id": "7"
}]
}]
}, {
"id": "10"
}, {
"id": "12"
}]
};
我想从树中的 ID 生成平面数组。
例如://["1", "2", "3", "4", "5", "6", "7", "10", "12"]
我想到了,
function getNestedArraysOfIds(node) {
if (node.children == undefined) {
return [node.id];
} else {
return [node.id,...node.children.map(subnode => (subnode.children==undefined) ? subnode.id: getNestedArraysOfIds(subnode))];
}
}
function getIds(array) {
return array.reduce((acc, subArray) =>
(Array.isArray(subArray)) ? [...acc, ...getIds(subArray)] : [...acc, subArray]);
}
var idArrays = getNestedArraysOfIds(datascource );
var ids = getIds(idArrays); //["1", "2", "3", "4", "5", "6", "7", "10", "12"]
我曾尝试使用单个 reduce 函数来完成它,但我最终写了两个函数,它们都是递归的。有没有很多优雅有效的方法可以用单一的 reduce 函数来做到这一点?
提前谢谢你。
使用 Array.flatMap()
的递归并传播以获得 id 和 children 的 id,然后展平为单个数组:
const getIds = ({ id, children }) => children ? [id, ...children.flatMap(getIds)] : id;
const dataSource = {"id":"1","children":[{"id":"2"},{"id":"3","children":[{"id":"4"},{"id":"5","children":[{"id":"6"},{"id":"7"}]}]},{"id":"10"},{"id":"12"}]};
const result = getIds(dataSource);
console.log(result);
您可以通过使用 concat
进行映射来平整 children。
function getFlat({ id, children = [] }) {
return [id].concat(...children.map(getFlat));
}
var data = { id: "1", children: [{ id: "2" }, { id: "3", children: [{ id: "4" }, { id: "5", children: [{ id: "6" }, { id: "7" }] }] }, { id: "10" }, { id: "12" }] };
console.log(getFlat(data));
与 reduce 函数相同
function getFlat({ id, children = [] }) {
return children.reduce((r, o) => [...r, ...getFlat(o)], [id]);
}
var data = { id: "1", children: [{ id: "2" }, { id: "3", children: [{ id: "4" }, { id: "5", children: [{ id: "6" }, { id: "7" }] }] }, { id: "10" }, { id: "12" }] };
console.log(getFlat(data));
您可以创建一个简单的 recursive
函数并使用 for..in
对其进行迭代。如果键是 id
然后将它的值推送到一个数组,否则如果键的值是一个数组,例如 children
键的值是一个数组,然后调用相同的递归在for循环中运行并传递每个对象
let datascource = {
"id": "1",
"children": [{
"id": "2"
}, {
"id": "3",
"children": [{
"id": "4"
}, {
"id": "5",
"children": [{
"id": "6"
}, {
"id": "7"
}]
}]
}, {
"id": "10"
}, {
"id": "12"
}]
};
let data = [];
function flatData(obj) {
for (let keys in obj) {
if (keys === 'id') {
data.push(obj[keys])
} else if (Array.isArray(obj[keys])) {
obj[keys].forEach((item) => {
flatData(item)
})
}
}
}
flatData(datascource)
console.log(data)