【问题标题】:Indexing through JSON array通过 JSON 数组进行索引
【发布时间】:2023-03-22 11:07:01
【问题描述】:

我正在尝试通过 JavaScript 中的 JSON 列表建立索引,但我在让它工作时遇到了很多麻烦。

我尝试通过每个 JSON 项的值进行索引,但它没有输出我想要的。我想我可以让它工作,但这将是一个额外不必要的循环级别。这是我的 JSON:https://pastebin.com/iYmaA4c5。如果您认为重新格式化 JSON 会更好,那么这也可能会有所帮助。

function output_json(data) {
    var i, j, k;
    for (i=0; i<Object.keys(data).length; i++) {
        group_=Object.values(data)[i];
        for (j=0; j<Object.keys(group_).length; j++) {
            person=Object.values(group_)[j];
            person_id=Object.keys(person)[0];
            console.log(person_id);
            for (k=0; k<Object.keys(person).length; k++) {
                person_info=Object.values(person)[k][0];
                console.log(person_info);
            }
        }
    }
}

我希望它打印出 id,然后是每个 id 的名称、注册 1、注册 2、周和 half_term。目前打印如下:

HA09_000

{name:“Wyatt Feldt”,registration_1:“R”,registration_2:“R”,周:0,half_term:1}

但我希望它为每一个都这样打印:

HA09_000

怀亚特·费尔特

R

R

0

1

这是我想要实现的一些伪代码:

FOR GROUP IN DATA:
    FOR PERSON IN GROUP:
        PRINT(PERSON.ID)
        FOR INFO IN PERSON:
            PRINT(INFO)

谢谢。

编辑:这是我用来检索数据的函数:

$.getJSON("http://localhost:8000/data.json", function(data) {
    output_json(data);
});

【问题讨论】:

  • 如果你需要Object.keys()那么它不是JSON而是一个对象-> What is the difference between JSON and Object Literal Notation?
  • @Andreas 好的,谢谢,但这对我有什么帮助?
  • 你不想学习一些可以让你以后的生活更轻松,或者可以纠正错误理解的东西(因为字符串和对象完全不同)吗?
  • @Andreas 当然是的,但是如果能以一种能帮助我更好地理解如何解决我的问题的方式学习它会很好。
  • 你的 for 循环/函数上是否缺少右括号 }?

标签: javascript json


【解决方案1】:

使用 for/in 循环遍历对象的属性。

我已将 for/in 循环添加到您的代码中(使用 person_info 对象)并对其进行了测试,它正在打印您想要的内容。 希望这会有所帮助。

function output_json(data) {
    var i, j, k;
    for (i=0; i<Object.keys(data).length; i++) {
        group_=Object.values(data)[i];
        for (j=0; j<Object.keys(group_).length; j++) {
            person=Object.values(group_)[j];
            person_id=Object.keys(person)[0];   
            console.log(person_id);
            for (k=0; k<Object.keys(person).length; k++) {
                person_info=Object.values(person)[k][0];
                //loop through the properties of the person_info object
                //using a for/in loop
                for (var key in person_info) {
                   console.log(person_info[key]); 
                }              
            }
        }
    }
}

【讨论】:

    【解决方案2】:

    两个有用的想法:(1)对象:如果有一天这将是一个真正的系统,并且来自服务的数据代表一群人,那么代码也应该这样说。作为一个例子,我包含了一个简单的Person 对象,它知道如何从平面表示中构建自己,并且知道如何在控制台上呈现自己。 (2) 键序未确定在JS对象中。要从特定排序的键中获取值,必须指定排序。 person print() 方法使用数组来执行此操作。

    在此处查看,在数据子集上运行...

    $.getJSON("http://localhost:8000/data.json", function(data) {
        print_items(data);
    });
    
    class Person {
        constructor(data) {
            this.id = Object.keys(data)[0];
            this.state = data[this.id][0];
        }
        print() {
            console.log(this.id);
            let displayKeys = ['name', 'registration_1', 'registration_2', 'week', 'half_term'];
            displayKeys.forEach(key => console.log(this.state[key]));
        }
        asTableRow() {
            let displayKeys = ['name', 'registration_1', 'registration_2', 'week', 'half_term'];
            let tds = displayKeys.map(key => `<td>${this.state[key]}</td>`);
            return `<tr>${tds}</tr>`;
        }
    }
    
    function print_items(data) {
        Object.keys(data).forEach(groupKey => {
            let group = data[groupKey];
            Object.keys(group).forEach(personKey => {
                let person = new Person(group[personKey]);
                person.print();
            });
        });
    }
    

    【讨论】:

    • 谢谢。这很有效并且很有意义。我只是做了一个小编辑,使它与我的 localhost JSON 文件一起工作,并且我还把它变成了一个函数。
    • 我遇到了一些麻烦。我不习惯这种格式,我无法让它与我真正想要做的事情一起工作。我真正需要它做的是为每个人在表中插入一行,每行包含 6 个单元格(groupKey、name、registration_1、registration_2、week、half_term)。我只是不明白你的代码足以让它工作。我之前的做法是这样的:pastebin.com/B3gbUinm(我添加了一个预期的结果)。很抱歉寻求更多帮助,但我只是不知道如何让您的代码做到这一点。
    • 这很好地说明了为什么对象是好的。我添加了一个方法,由此 Person 对象可以将自身呈现为表格行。我想你会从中看到如何从 N 个人那里获取 N 行,并且应该直接用表格标签包装它。 (注意,People 上的静态方法可能是一个好地方。还要注意displayKeys 可能会成为它自己的静态方法。它对两个实例方法很有用,对“headerRow() ` 方法。我将这些留作练习,因为我必须离线大约 12 小时,但稍后可以提供帮助)
    【解决方案3】:

    您可以通过查看每个键并仅传递值来清理内部循环。另外我建议将Object.keys(person).length 从你的 for 循环中拉出来,因为它会处理每个循环上的键。如果您将它们放入一个变量并引用它,它会避免重新评估键。

        var groups = Object.keys(testData);
        for(var i = 0; i<groups.length; i++){
            var group = testData[groups[i]];
            for(var j = 0; j<group.length; j++){
                var personEntry = group[j];
                var person_id = Object.keys(personEntry)[0];
                console.log(person_id);
                var personEntries = personEntry[person_id];
                for(var k = 0; k<personEntries.length; k++){
                    var personValues = Object.values(personEntries[k]);
                    for(var l = 0; l<personValues.length; l++){
                        console.log(personValues[l]);
                    }
                }
            }
        }
    

    【讨论】:

    • 不幸的是,它似乎不起作用。它只是为每个人输出 "HA09_000" 然后 "0: {name: "Wyatt Feldt", registration_1: "R", registration_2: "R", week: 0, half_term: 1}"。
    • 我看到你编辑了你的帖子,但现在它打印“HA09_000”“H”“A”“0”“9”。
    • 我不得不重新设计它,因为以前的结构不容易理解。试试这个吧。
    • 谢谢,但这是我在问题中引用的方法(需要额外的 for 循环)。我确信有办法做到这一点,就像我在我的伪代码中描述的那样(即 3 个 for 循环)。
    猜你喜欢
    • 2018-05-02
    • 1970-01-01
    • 2017-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-04
    • 2018-08-20
    • 1970-01-01
    相关资源
    最近更新 更多