如何遍历这个嵌套数组并从每个项目创建一个模型?[爪哇]

How can I loop through this nested array and create a model from each item? [Java]

提问人:Sherbet Head 提问时间:5/20/2023 最后编辑:Sherbet Head 更新时间:10/29/2023 访问量:118

问:

假设这里的每个 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;
}
    
Java 循环 递归 嵌套

评论

1赞 Reilas 5/20/2023
为了澄清您的问题,您想遍历结构并返回所有对象的列表,并且这些对象应该具有正确嵌套的列表,以防它们有子对象?PersonPerson
0赞 Old Dog Programmer 5/20/2023
请编辑问题。如果您同时显示示例输入和所需结果,这将有所帮助。我建议在示例中添加一到三个额外的人。此外,请考虑将代码呈现为最小可重现示例,其中应包括 的相关部分。class Person

答:

0赞 queeg 5/20/2023 #1

对于每个人,您都有给定的“孩子”信息。这隐含地使那个人成为孩子的父母。从你的数据来看,它在很大程度上是递归的,但如果你愿意,也可以用迭代来解决。取决于在内存中承载对象的方式。

因此,遍历所有人员(有/没有递归)。与该人(名为 P)一起遍历所有子项(名为 C)。将孩子的父关系设置为 P。

在程序的某些改进版本中,您可以在设置子项的父项之前检查之前是否没有父项注册,或者如果设置了父项,则该父项应与要设置的父项没有什么不同。这样,您就可以验证一些输入数据。

1赞 Reilas 5/20/2023 #2

这是一个算法;我没有改编你的代码,因为我无权访问许多对象。

你是对的,递归调用是完成此操作所需的,尽管我确信还有其他可用的措施。

让我们考虑以下内容,一个保存信息的类,称之为 。
我还提供了一个覆盖的方法,因此我们可以将信息打印出来。
PersontoString

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";
        }
    }
}

从这里开始,我创建了一个类,称为 ,它包含一个字段和一个方法。
该字段是 的 ,我们将使用它来保存递归方法生成的数据。
该方法是一个递归函数,它将遍历给定的列表,并将该人添加到列表中。
随后,如果此人有孩子,他们也会通过递归调用和提供列表添加到列表中。
ExampleListPerson

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);
}