提问人:Sherbet Head 提问时间:5/20/2023 最后编辑:Sherbet Head 更新时间:10/29/2023 访问量:118
如何遍历这个嵌套数组并从每个项目创建一个模型?[爪哇]
How can I loop through this nested array and create a model from each item? [Java]
问:
假设这里的每个 Person 有 3 个键值对:姓名、年龄和孩子。我想遍历可能无穷无尽的嵌套列表,并从每个人创建一个新的“父”模型。在每个 person 模型中,我需要为每个嵌套级别创建一个 List of Person 模型,如果某个特定人员有一个子项,则该 Person 模型的 children 属性将包含正确子项的后续 List。(请注意,主要生成的 Persons 嵌套列表存储在内存中的其他地方,我只需要帮助创建它们,就像我的示例中一样)
Example Structure:
Persons
- Person
- Person
- Person
- Person
- Person
- Person
- Person
Each Person above has a name, age, and children property.
ex.
{Persons:
[name: John, age: 18, children: null},
{name: Lisa, age: 32, children: [{ name: Tyler, age: 7, children: null}],
{name: Mike, age: 90, children: [{name: Derek, age 50, children:
[{name: Mary, age:25, children: null},
{name: Beth, age:16, children: null}]}]};
递归不是我最强的领域,我正在为如何遍历一个可能非常深的嵌套对象而苦苦挣扎。我知道这是非常错误的,因为我只覆盖了嵌套的第一层。我想我应该像我在底部写的那样使用createPerson方法,并使用递归函数来,但我很挣扎。任何见解都非常感谢!
ListPerson API 返回 Persons[] 人
private void loadPersons(String id) {
ListPersonsApi.Request request = Jso.create();
request.id = id;
dispatcher.send(ListPersonsApi.PATH, request, r-> {
for (ListPersonsApi.persons p : r.persons) {
List<Person> persons = new ArrayList<>();
PersonModel person = new Person();
person.name = p.name;
person.age = p.age;
persons.add(person);
parent.children = persons;
// Everything below this is wrong of course but its the logic I was thinking of using
List<Person> children = p.children;
while(children != null) {
for (ListPersonsApi.persons q : p.children) {
createPerson(p, q)
children = children.children;
}
})
}
private void createPerson(PersonModel parent, p) {
List<Person> persons = new ArrayList<>();
PersonModel person = new Person();
person.name = p.name;
person.age = p.age;
persons.add(person);
parent.children = persons;
}
答:
对于每个人,您都有给定的“孩子”信息。这隐含地使那个人成为孩子的父母。从你的数据来看,它在很大程度上是递归的,但如果你愿意,也可以用迭代来解决。取决于在内存中承载对象的方式。
因此,遍历所有人员(有/没有递归)。与该人(名为 P)一起遍历所有子项(名为 C)。将孩子的父关系设置为 P。
在程序的某些改进版本中,您可以在设置子项的父项之前检查之前是否没有父项注册,或者如果设置了父项,则该父项应与要设置的父项没有什么不同。这样,您就可以验证一些输入数据。
这是一个算法;我没有改编你的代码,因为我无权访问许多对象。
你是对的,递归调用是完成此操作所需的,尽管我确信还有其他可用的措施。
让我们考虑以下内容,一个保存信息的类,称之为 。
我还提供了一个覆盖的方法,因此我们可以将信息打印出来。Person
toString
static class Person {
String name;
int age;
List<Person> children;
Person(String name, int age) {
this.name = name;
this.age = age;
}
Person(String name, int age, List<Person> children) {
this.name = name;
this.age = age;
this.children = children;
}
@Override
public String toString() {
String string = "'%s', %d, ".formatted(name, age);
if (children == null)
return string + "no children";
else {
if (children.size() == 1) return string + "1 child";
else return string + children.size() + " children";
}
}
}
从这里开始,我创建了一个类,称为 ,它包含一个字段和一个方法。
该字段是 的 ,我们将使用它来保存递归方法生成的数据。
该方法是一个递归函数,它将遍历给定的列表,并将该人添加到列表中。
随后,如果此人有孩子,他们也会通过递归调用和提供列表添加到列表中。Example
List
Person
List<Person> persons = new ArrayList<>();
void persons(List<Person> list) {
for (Person person : list) {
persons.add(person);
if (person.children != null) {
persons(person.children);
}
}
}
在另一个方法中,我填充了一个列表,用于演示目的。
它等同于您提供的示例数据,具有相同的姓名、年龄和孩子。
如果我运行类并打印,我会得到以下数据。persons
'John', 18, no children
'Lisa', 32, 1 child
'Tyler', 7, no children
'Mike', 90, 1 child
'Derek', 50, 2 children
'Mary', 25, no children
'Beth', 16, no children
因此,如果我是正确的,鉴于这些过程,您可以将方法更改为以下内容。loadPersons
private void loadPersons(String id) {
ListPersonsApi.Request request = Jso.create();
request.id = id;
List<Person> list = new ArrayList<>();
dispatcher.send(ListPersonsApi.PATH, request, r -> {
for (ListPersonsApi.persons p : r.persons)
list.add(new Person(p.name, p.age, p.children));
});
persons(list);
}
上一个:将循环中的函数应用于数据帧列表
评论
Person
Person
class Person