遍历 javascript 中的缩进数组
Traversing through indented arrays in javascript
我有一个 javascript 对象如下:
let hogwartsHeirarchy = {
Headmaster: [
{
name: "Professor Dumbledore",
key: 1,
Headmistress: [
{
name: "Minerva McGonagall",
key: 2,
StandByProfessor: [
{
name: "Rubeus Hagrid",
subject: "Potions Master",
key: 3,
Professor: [
{ name: "Horace Slughorn", key: 4 },
{ name: "Severus Snape", key: 4 },
],
},
{
name: "Alastor Moody",
subject: "Defense Against the Dark Arts",
key: 3,
Professor: [
{ name: "Remus Lupin", key: 4 },
{ name: "Gilderoy Lockhart", key: 4 },
],
},
],
},
],
},
],
};
我想要 print/get 每个节点值 [headmaster, headmastress,..] 及其对应的子值。我尝试了各种方法,例如使用 for 循环遍历数组、递归等,但不幸的是我无法从节点中获取任何值。请帮忙。
例如:我用过这个:
printArray(hogwartsHeirarchy);
function printArray(arr){
for(var i = 0; i < arr.length; i++){
if(arr[i] instanceof Array){
console.log("true: ");
console.log("intermediate one : ",arr[i]);
printArray(arr[i]);
}else{
console.log("final one : ",arr[i]);
}
}
}
值可以以这种格式显示:
Headmaster - name : Professor Dumbledore, key : 1
.
.
StandByProfessor - name : Robeus Hagrid, subject : Potion Master, key : 3
StandByProfessor - name : Alastor Moody, subject : Defence against the dark arts, key : 3
.
.
Professor - ...
Professor - ...
Professor - ...
Professor - ...
您可以从对象中删除已知键并获取类型层次结构,然后仅当类型存在时才迭代 属性 和 return 类型、名称、主题和键的元组。
const
getValues = (object, type) => [
...(type ? [`${type} - name : ${object.name}, ${object.subject ? `subject : ${object.subject}, ` : ''}key : ${object.key}`] : []),
...Object
.keys(object)
.filter(k => !['name', 'subject', 'key'].includes(k))
.flatMap(k => object[k].flatMap(o => getValues(o, k)))
],
hogwartsHierarchy = { Headmaster: [{ name: "Professor Dumbledore", key: 1, Headmistress: [{ name: "Minerva McGonagall", key: 2, StandByProfessor: [{ name: "Rubeus Hagrid", subject: "Potions Master", key: 3, Professor: [{ name: "Horace Slughorn", key: 4 }, { name: "Severus Snape", key: 4 }] }, { name: "Alastor Moody", subject: "Defense Against the Dark Arts", key: 3, Professor: [{ name: "Remus Lupin", key: 4 }, { name: "Gilderoy Lockhart", key: 4 }] }] }] }] };
console.log(getValues(hogwartsHierarchy));
.as-console-wrapper { max-height: 100% !important; top: 0; }
我建议重组,以便始终使用相同的密钥访问下级,从而可以非常简单地访问。我还做到了,所以每个节点都是一个人,顶部没有不是人的对象。我留下了变量名,但它现在直接引用 Dumbledore。
let hogwartsHeirarchy =
{
name: "Professor Dumbledore",
role: "Headmaster",
key: 1,
subordinates: [
{
name: "Minerva McGonagall",
role: "Headmistress",
key: 2,
subordinates: [
{
name: "Rubeus Hagrid",
role: "StandByProfessor",
subject: "Potions Master",
key: 3,
subordinates: [
{ name: "Horace Slughorn", key: 4, role: "Professor" },
{ name: "Severus Snape", key: 4, role: "Professor" },
],
},
{
name: "Alastor Moody",
role: "StandByProfessor",
subject: "Defense Against the Dark Arts",
key: 3,
subordinates: [
{ name: "Remus Lupin", key: 4, role: "Professor" },
{ name: "Gilderoy Lockhart", key: 4, role: "Professor" },
],
},
],
},
],
};
function visitStaff(staffMember) {
if (staffMember.subordinates) {
for (const subordinate of staffMember.subordinates) {
visitStaff(subordinate);
}
}
console.log("Staff member:", staffMember);
}
visitStaff(hogwartsHeirarchy);
设置数据结构时,重要的是要考虑如何访问它,以及它的定义部分是什么。在这种情况下,有人是节点,有(从属)关系,是图的边。
在您的原始代码中,您有一个对象 { Headmaster: [...] }
— 它代表什么?是人吗?不;这是一种关系吗?有点,但没有。它定义了关于 Dumbledoor 的一些事情,即他是校长,但没有定义他是谁或什么是 of 的校长。所以它实际上只是在描述 Dumbledoor 的 role/job 头衔,因此作为此人的 属性 更有意义。它作为一个对象是多余的。
它有助于对齐您的对象,使它们都代表某种东西。您应该能够描述每个对象和数组是什么。
给定数据结构:
a) 我假设每种类型的“标题”中只有一个数组,并且
b) 该数组将包含与 parent
结构相似的 object 列表
有可能...
- 使用
for..of
以便
- 遍历 object 上的每个键,并将它们添加到字符串中。因为有数组包含objects,
- 我可以遍历它们,并且
- 通过让方法调用自身来执行递归循环。
const hogwartsHierarchy = { Headmaster: [{ name: "Professor Dumbledore", key: 1, Headmistress: [{ name: "Minerva McGonagall", key: 2, StandByProfessor: [{ name: "Rubeus Hagrid", subject: "Potions Master", key: 3, Professor: [{ name: "Horace Slughorn", key: 4 }, { name: "Severus Snape", key: 4 }] }, { name: "Alastor Moody", subject: "Defense Against the Dark Arts", key: 3, Professor: [{ name: "Remus Lupin", key: 4 }, { name: "Gilderoy Lockhart", key: 4 }] }] }] }] };
function printAllWithChilds(obj, prevProp) {
let listItem = (prevProp) ? ' -- ' + prevProp : '';
for (const property in obj) { // 1
if (obj[property] instanceof Array) {
obj[property].forEach((child_obj) => { // 3
listItem += printAllWithChilds(child_obj, property); // 4
});
} else {
listItem += `, ${property}: ${obj[property]}`; // 2
}
}
return listItem;
}
let listStr = printAllWithChilds(hogwartsHierarchy);
console.log(listStr);
老实说,我会按照一种数据库结构将 hogwartsHierarchy
分成更小的部分,其中 primary_key
对每个人都是唯一的。这些数组没有多大意义,直到您查看变量 professors
以及它们各自的 belongs_to
键如何对应于 standbyprofessors
,您可以在其中看到“Horace Slughorn”属于“鲁伯·海格”。
const headermaster = {
name: "Professor Dumbledore",
primary_key: 1
};
const headmistress = {
name: "Minerva McGonagall",
primary_key: 2,
belongs_to: 1
};
const standbyprofessors = [{
name: "Rubeus Hagrid",
subject: "Potions Master",
primary_key: 3,
belongs_to: 2
},
{
name: "Alastor Moody",
subject: "Defense Against the Dark Arts",
primary_key: 4,
belongs_to: 2
}
];
const professors = [{
name: "Horace Slughorn",
primary_key: 5,
belongs_to: 3
},
{
name: "Severus Snape",
primary_key: 6,
belongs_to: 3
},
{
name: "Remus Lupin",
primary_key: 7,
belongs_to: 4
},
{
name: "Gilderoy Lockhart",
primary_key: 8,
belongs_to: 4
},
];
基于 1j01 对象模型:
const hogwartsHeirarchy =
{ name: "Professor Dumbledore", role: "Headmaster", key: 1,
subordinates: [{ name: "Minerva McGonagall", role: "Headmistress", key: 2,
subordinates: [
{ name: "Rubeus Hagrid", role: "StandByProfessor", subject: "Potions Master", key: 3,
subordinates: [
{ name: "Horace Slughorn", key: 4, role: "Professor" },
{ name: "Severus Snape", key: 4, role: "Professor" }]},
{ name: "Alastor Moody", role: "StandByProfessor", subject: "Defense Against the Dark Arts", key: 3,
subordinates: [
{ name: "Remus Lupin", key: 4, role: "Professor" },
{ name: "Gilderoy Lockhart", key: 4, role: "Professor" }]}]}]};
const visitStaff = (staffMember) => {
const iter = (obj) => {
const { name, role, key, subordinates } = obj;
const subject = obj.subject ? `, subject : ${obj.subject}` : '';
const line = `${role} - name : ${name}${subject}, key : ${key}`;
const sublines = (Array.isArray(subordinates)) ? subordinates.flatMap(iter) : [];
return [line, ...sublines];
}
return iter(staffMember).join('\n');
}
console.log(visitStaff(hogwartsHeirarchy));
.as-console-wrapper { max-height: 100% !important; top: 0; }
我有一个 javascript 对象如下:
let hogwartsHeirarchy = {
Headmaster: [
{
name: "Professor Dumbledore",
key: 1,
Headmistress: [
{
name: "Minerva McGonagall",
key: 2,
StandByProfessor: [
{
name: "Rubeus Hagrid",
subject: "Potions Master",
key: 3,
Professor: [
{ name: "Horace Slughorn", key: 4 },
{ name: "Severus Snape", key: 4 },
],
},
{
name: "Alastor Moody",
subject: "Defense Against the Dark Arts",
key: 3,
Professor: [
{ name: "Remus Lupin", key: 4 },
{ name: "Gilderoy Lockhart", key: 4 },
],
},
],
},
],
},
],
};
我想要 print/get 每个节点值 [headmaster, headmastress,..] 及其对应的子值。我尝试了各种方法,例如使用 for 循环遍历数组、递归等,但不幸的是我无法从节点中获取任何值。请帮忙。
例如:我用过这个:
printArray(hogwartsHeirarchy);
function printArray(arr){
for(var i = 0; i < arr.length; i++){
if(arr[i] instanceof Array){
console.log("true: ");
console.log("intermediate one : ",arr[i]);
printArray(arr[i]);
}else{
console.log("final one : ",arr[i]);
}
}
}
值可以以这种格式显示:
Headmaster - name : Professor Dumbledore, key : 1
.
.
StandByProfessor - name : Robeus Hagrid, subject : Potion Master, key : 3
StandByProfessor - name : Alastor Moody, subject : Defence against the dark arts, key : 3
.
.
Professor - ...
Professor - ...
Professor - ...
Professor - ...
您可以从对象中删除已知键并获取类型层次结构,然后仅当类型存在时才迭代 属性 和 return 类型、名称、主题和键的元组。
const
getValues = (object, type) => [
...(type ? [`${type} - name : ${object.name}, ${object.subject ? `subject : ${object.subject}, ` : ''}key : ${object.key}`] : []),
...Object
.keys(object)
.filter(k => !['name', 'subject', 'key'].includes(k))
.flatMap(k => object[k].flatMap(o => getValues(o, k)))
],
hogwartsHierarchy = { Headmaster: [{ name: "Professor Dumbledore", key: 1, Headmistress: [{ name: "Minerva McGonagall", key: 2, StandByProfessor: [{ name: "Rubeus Hagrid", subject: "Potions Master", key: 3, Professor: [{ name: "Horace Slughorn", key: 4 }, { name: "Severus Snape", key: 4 }] }, { name: "Alastor Moody", subject: "Defense Against the Dark Arts", key: 3, Professor: [{ name: "Remus Lupin", key: 4 }, { name: "Gilderoy Lockhart", key: 4 }] }] }] }] };
console.log(getValues(hogwartsHierarchy));
.as-console-wrapper { max-height: 100% !important; top: 0; }
我建议重组,以便始终使用相同的密钥访问下级,从而可以非常简单地访问。我还做到了,所以每个节点都是一个人,顶部没有不是人的对象。我留下了变量名,但它现在直接引用 Dumbledore。
let hogwartsHeirarchy =
{
name: "Professor Dumbledore",
role: "Headmaster",
key: 1,
subordinates: [
{
name: "Minerva McGonagall",
role: "Headmistress",
key: 2,
subordinates: [
{
name: "Rubeus Hagrid",
role: "StandByProfessor",
subject: "Potions Master",
key: 3,
subordinates: [
{ name: "Horace Slughorn", key: 4, role: "Professor" },
{ name: "Severus Snape", key: 4, role: "Professor" },
],
},
{
name: "Alastor Moody",
role: "StandByProfessor",
subject: "Defense Against the Dark Arts",
key: 3,
subordinates: [
{ name: "Remus Lupin", key: 4, role: "Professor" },
{ name: "Gilderoy Lockhart", key: 4, role: "Professor" },
],
},
],
},
],
};
function visitStaff(staffMember) {
if (staffMember.subordinates) {
for (const subordinate of staffMember.subordinates) {
visitStaff(subordinate);
}
}
console.log("Staff member:", staffMember);
}
visitStaff(hogwartsHeirarchy);
设置数据结构时,重要的是要考虑如何访问它,以及它的定义部分是什么。在这种情况下,有人是节点,有(从属)关系,是图的边。
在您的原始代码中,您有一个对象 { Headmaster: [...] }
— 它代表什么?是人吗?不;这是一种关系吗?有点,但没有。它定义了关于 Dumbledoor 的一些事情,即他是校长,但没有定义他是谁或什么是 of 的校长。所以它实际上只是在描述 Dumbledoor 的 role/job 头衔,因此作为此人的 属性 更有意义。它作为一个对象是多余的。
它有助于对齐您的对象,使它们都代表某种东西。您应该能够描述每个对象和数组是什么。
给定数据结构:
a) 我假设每种类型的“标题”中只有一个数组,并且
b) 该数组将包含与 parent
有可能...
- 使用
for..of
以便 - 遍历 object 上的每个键,并将它们添加到字符串中。因为有数组包含objects,
- 我可以遍历它们,并且
- 通过让方法调用自身来执行递归循环。
const hogwartsHierarchy = { Headmaster: [{ name: "Professor Dumbledore", key: 1, Headmistress: [{ name: "Minerva McGonagall", key: 2, StandByProfessor: [{ name: "Rubeus Hagrid", subject: "Potions Master", key: 3, Professor: [{ name: "Horace Slughorn", key: 4 }, { name: "Severus Snape", key: 4 }] }, { name: "Alastor Moody", subject: "Defense Against the Dark Arts", key: 3, Professor: [{ name: "Remus Lupin", key: 4 }, { name: "Gilderoy Lockhart", key: 4 }] }] }] }] };
function printAllWithChilds(obj, prevProp) {
let listItem = (prevProp) ? ' -- ' + prevProp : '';
for (const property in obj) { // 1
if (obj[property] instanceof Array) {
obj[property].forEach((child_obj) => { // 3
listItem += printAllWithChilds(child_obj, property); // 4
});
} else {
listItem += `, ${property}: ${obj[property]}`; // 2
}
}
return listItem;
}
let listStr = printAllWithChilds(hogwartsHierarchy);
console.log(listStr);
老实说,我会按照一种数据库结构将 hogwartsHierarchy
分成更小的部分,其中 primary_key
对每个人都是唯一的。这些数组没有多大意义,直到您查看变量 professors
以及它们各自的 belongs_to
键如何对应于 standbyprofessors
,您可以在其中看到“Horace Slughorn”属于“鲁伯·海格”。
const headermaster = {
name: "Professor Dumbledore",
primary_key: 1
};
const headmistress = {
name: "Minerva McGonagall",
primary_key: 2,
belongs_to: 1
};
const standbyprofessors = [{
name: "Rubeus Hagrid",
subject: "Potions Master",
primary_key: 3,
belongs_to: 2
},
{
name: "Alastor Moody",
subject: "Defense Against the Dark Arts",
primary_key: 4,
belongs_to: 2
}
];
const professors = [{
name: "Horace Slughorn",
primary_key: 5,
belongs_to: 3
},
{
name: "Severus Snape",
primary_key: 6,
belongs_to: 3
},
{
name: "Remus Lupin",
primary_key: 7,
belongs_to: 4
},
{
name: "Gilderoy Lockhart",
primary_key: 8,
belongs_to: 4
},
];
基于 1j01 对象模型:
const hogwartsHeirarchy =
{ name: "Professor Dumbledore", role: "Headmaster", key: 1,
subordinates: [{ name: "Minerva McGonagall", role: "Headmistress", key: 2,
subordinates: [
{ name: "Rubeus Hagrid", role: "StandByProfessor", subject: "Potions Master", key: 3,
subordinates: [
{ name: "Horace Slughorn", key: 4, role: "Professor" },
{ name: "Severus Snape", key: 4, role: "Professor" }]},
{ name: "Alastor Moody", role: "StandByProfessor", subject: "Defense Against the Dark Arts", key: 3,
subordinates: [
{ name: "Remus Lupin", key: 4, role: "Professor" },
{ name: "Gilderoy Lockhart", key: 4, role: "Professor" }]}]}]};
const visitStaff = (staffMember) => {
const iter = (obj) => {
const { name, role, key, subordinates } = obj;
const subject = obj.subject ? `, subject : ${obj.subject}` : '';
const line = `${role} - name : ${name}${subject}, key : ${key}`;
const sublines = (Array.isArray(subordinates)) ? subordinates.flatMap(iter) : [];
return [line, ...sublines];
}
return iter(staffMember).join('\n');
}
console.log(visitStaff(hogwartsHeirarchy));
.as-console-wrapper { max-height: 100% !important; top: 0; }