为 javascript 中多级类别的每个子项添加破折号
Add dash to each child of multi level category in javascript
我有一个像这样的多级类别数组:
[
{
"id": 5,
"parent_id": 3,
"name": "Fruits",
"parent": {
"id": 3,
"parent_id": 1,
"name": "Vegetables and fruits",
}
},
{
"id": 6,
"parent_id": 3,
"name": "Vegetables",
"parent": {
"id": 3,
"parent_id": 1,
"name": "Vegetables and fruits",
}
},
{
"id": 3,
"parent_id": null,
"name": "Vegetables and fruits",
"parent": null
},
]
我想根据级别为类别的每个子项添加“-”(破折号)前缀。例如,第一层有一个破折号'-',第三层有两个破折号'--'。
如何像这样更新数组?
我尝试了一些代码。
const updateData = (data) => {
return data.map(item => {
if (item.parent_id != null) {
// Maybe there use recursive
item.name = `-${item.name }`;
}
return item;
})
}
异常输出:
Vegetables and fruits
Drinks
-Fruits
-Vegetables
--Tomatos
--Potatos
我们可以创建一个 getLevel
函数来确定任何节点的级别,然后使用它来决定要使用的破折号数量:
let input = [ { "id": 5, "parent_id": 3, "name": "Fruits", "parent": { "id": 3, "parent_id": 1, "name": "Vegetables and fruits", } }, { "id": 6, "parent_id": 3, "name": "Vegetables", "parent": { "id": 3, "parent_id": 1, "name": "Vegetables and fruits", } }, { "id": 3, "parent_id": null, "name": "Vegetables and fruits", "parent": null }, { "id": 7, "parent_id": 5, "name": "Strawberries", "parent": { "id": 5, "parent_id": 3, "name": "Vegetables and fruits", } }, { "id": 8, "parent_id": 6, "name": "Tomatos", "parent": { "id": 6, "parent_id": 3, "name": "Vegetables and fruits", } }, ]
// Pre-compute object / parent mapping
const parentMap = input.reduce((acc,obj) => {
acc[obj.id] = obj?.parent;
return acc;
}, {})
// Find the node level based on its parent id.
function getLevel(parentMap, obj) {
let level = 0;
while (parentMap[obj.id]) {
level++;
obj = parentMap[obj.id]
}
return level;
}
const result = input.map(obj => {
level = getLevel(parentMap , obj);
return { ...obj, level} ;
})
.sort((a,b) => a.level - b.level)
.map(obj => '-'.repeat(obj.level) + obj.name)
console.log('Result:', result)
一种方法是将您的输入转换为树列表(因为您可以有单独的根)。然后,遍历它们并递归打印它们就变得非常容易了。这是我将使用的实现:
const input = [
{
"id": 5,
"parent_id": 3,
"name": "Fruits",
"parent": {
"id": 3,
"parent_id": 1,
"name": "Vegetables and fruits",
}
},
{
"id": 6,
"parent_id": 3,
"name": "Vegetables",
"parent": {
"id": 3,
"parent_id": 1,
"name": "Vegetables and fruits",
}
},
{
"id": 3,
"parent_id": null,
"name": "Vegetables and fruits",
"parent": null
},
]
function buildTrees(input) {
const mapping = new Map()
// Creating a mapping based on the item id
input.forEach(i => {
delete i.parent // parent detail is not needed
i.children = []
mapping.set(i.id, i)
})
// Adding every node to its parent children list
input.filter(i => i.parent_id !== null).forEach(i => {
mapping.get(i.parent_id).children.push(i)
})
// Returning the roots
return input.filter(i => i.parent_id === null).map(i => mapping.get(i.id))
}
function printTree(tree, depth) {
// Recursively prints the names
console.log('-'.repeat(depth) + ' ' + tree.name)
tree.children.forEach(child => printTree(child, depth + 1))
}
const trees = buildTrees(input)
trees.forEach(tree => printTree(tree, 0))
我有一个像这样的多级类别数组:
[
{
"id": 5,
"parent_id": 3,
"name": "Fruits",
"parent": {
"id": 3,
"parent_id": 1,
"name": "Vegetables and fruits",
}
},
{
"id": 6,
"parent_id": 3,
"name": "Vegetables",
"parent": {
"id": 3,
"parent_id": 1,
"name": "Vegetables and fruits",
}
},
{
"id": 3,
"parent_id": null,
"name": "Vegetables and fruits",
"parent": null
},
]
我想根据级别为类别的每个子项添加“-”(破折号)前缀。例如,第一层有一个破折号'-',第三层有两个破折号'--'。
如何像这样更新数组?
我尝试了一些代码。
const updateData = (data) => {
return data.map(item => {
if (item.parent_id != null) {
// Maybe there use recursive
item.name = `-${item.name }`;
}
return item;
})
}
异常输出:
Vegetables and fruits
Drinks
-Fruits
-Vegetables
--Tomatos
--Potatos
我们可以创建一个 getLevel
函数来确定任何节点的级别,然后使用它来决定要使用的破折号数量:
let input = [ { "id": 5, "parent_id": 3, "name": "Fruits", "parent": { "id": 3, "parent_id": 1, "name": "Vegetables and fruits", } }, { "id": 6, "parent_id": 3, "name": "Vegetables", "parent": { "id": 3, "parent_id": 1, "name": "Vegetables and fruits", } }, { "id": 3, "parent_id": null, "name": "Vegetables and fruits", "parent": null }, { "id": 7, "parent_id": 5, "name": "Strawberries", "parent": { "id": 5, "parent_id": 3, "name": "Vegetables and fruits", } }, { "id": 8, "parent_id": 6, "name": "Tomatos", "parent": { "id": 6, "parent_id": 3, "name": "Vegetables and fruits", } }, ]
// Pre-compute object / parent mapping
const parentMap = input.reduce((acc,obj) => {
acc[obj.id] = obj?.parent;
return acc;
}, {})
// Find the node level based on its parent id.
function getLevel(parentMap, obj) {
let level = 0;
while (parentMap[obj.id]) {
level++;
obj = parentMap[obj.id]
}
return level;
}
const result = input.map(obj => {
level = getLevel(parentMap , obj);
return { ...obj, level} ;
})
.sort((a,b) => a.level - b.level)
.map(obj => '-'.repeat(obj.level) + obj.name)
console.log('Result:', result)
一种方法是将您的输入转换为树列表(因为您可以有单独的根)。然后,遍历它们并递归打印它们就变得非常容易了。这是我将使用的实现:
const input = [
{
"id": 5,
"parent_id": 3,
"name": "Fruits",
"parent": {
"id": 3,
"parent_id": 1,
"name": "Vegetables and fruits",
}
},
{
"id": 6,
"parent_id": 3,
"name": "Vegetables",
"parent": {
"id": 3,
"parent_id": 1,
"name": "Vegetables and fruits",
}
},
{
"id": 3,
"parent_id": null,
"name": "Vegetables and fruits",
"parent": null
},
]
function buildTrees(input) {
const mapping = new Map()
// Creating a mapping based on the item id
input.forEach(i => {
delete i.parent // parent detail is not needed
i.children = []
mapping.set(i.id, i)
})
// Adding every node to its parent children list
input.filter(i => i.parent_id !== null).forEach(i => {
mapping.get(i.parent_id).children.push(i)
})
// Returning the roots
return input.filter(i => i.parent_id === null).map(i => mapping.get(i.id))
}
function printTree(tree, depth) {
// Recursively prints the names
console.log('-'.repeat(depth) + ' ' + tree.name)
tree.children.forEach(child => printTree(child, depth + 1))
}
const trees = buildTrees(input)
trees.forEach(tree => printTree(tree, 0))