对象和数组的复杂JSON嵌套

43

我在处理JSON对象/数组的语法和结构时遇到了困难。

{ 
  "accounting" : [   
                     { "firstName" : "John",  
                       "lastName"  : "Doe",
                       "age"       : 23 },

                     { "firstName" : "Mary",  
                       "lastName"  : "Smith",
                        "age"      : 32 }
                 ],                            
  "sales"      : [ 
                     { "firstName" : "Sally", 
                       "lastName"  : "Green",
                        "age"      : 27 },

                     { "firstName" : "Jim",   
                       "lastName"  : "Galley",
                       "age"       : 41 }
                 ] 
} 

我想创建一个嵌套的对象和数组结构,以存储以下信息:

{
"problems": [{
    "Diabetes":[{
        "medications":[{
            "medicationsClasses":[{
                "className":[{
                    "associatedDrug":[{
                        "name":"asprin",
                        "dose":"",
                        "strength":"500 mg"
                    }],
                    "associatedDrug#2":[{
                        "name":"somethingElse",
                        "dose":"",
                        "strength":"500 mg"
                    }]
                }],
                "className2":[{
                    "associatedDrug":[{
                        "name":"asprin",
                        "dose":"",
                        "strength":"500 mg"
                    }],
                    "associatedDrug#2":[{
                        "name":"somethingElse",
                        "dose":"",
                        "strength":"500 mg"
                    }]
                }]
            }]
        }],
        "labs":[{
            "missing_field": "missing_value"
        }]
    }],
    "Asthma":[{}]
}]}

但是我不知道应该采取什么正确的方法。我应该只是创建JavaScript对象吗?对于这个项目来说,JSON是否有意义?

如何正确设置类似这样的语法?

以下是我的代码:

$(document).ready(function() {
    $.getJSON('js/orders.json', function(json) {
      $.each(json.problems, function(index, order) {
        $('.loadMeds').append('<p>' + order.name + '</p>')
      });
    });
});

我只是通过使用jQuery中的getJSON()调用JSON文件进行本地测试。这只是为了在生产环境中进行测试。服务器只是运行PHP的Apache。(对于服务器方面,我的知识也不是很丰富...) - Alex
1
我不确定你想通过这个问题得出什么结论。你应该以一种能够轻松处理数据的方式来组织数据,具体取决于你对数据的处理方式... 你有任何特定的技术问题吗?否则我看不出这个问题可回答性。 - Felix Kling
1
如果你的问题不是关于 JSON、XML 等,它们只是用作临时数据结构,那么你应该学习 SQL 并使用 PostgreSQL :) - gkaykck
@ Felix Kling,是的,我的技术问题是关于我的语法和结构是否正确... - Alex
无论你的语法是否正确,都可以通过诸如http://jsonlint.org/之类的工具找出。至于结构,这更多是概念性的而非技术性的,我倾向于认为这对于本网站来说过于局限或不相关。 - Felix Kling
显示剩余4条评论
5个回答

25

第一个代码示例是JavaScript代码的例子,它类似于JSON但不同。JSON中不会出现1)注释和2)var关键字。

您的JSON中没有注释,但应该删除var并像这样开始:

orders: {

[{}] 表示“数组中的对象”,并非在所有情况下都需要使用。它不是错误,但对于某些目的而言过于复杂。使用 AssociatedDrug 作为对象可能会更好:

"associatedDrug": {
                "name":"asprin",
                "dose":"",
                "strength":"500 mg"
          }

此外,空的对象应该填充一些内容。

除此之外,你的代码还可以。你可以将其粘贴到JavaScript中,或使用JSON.parse()方法或其他任何解析方法(请不要使用eval)。

更新2已解答:

obj.problems[0].Diabetes[0].medications[0].medicationsClasses[0].className[0].associatedDrug[0].name

返回 'aspirin'。但它更适合在任何foreaches中使用。


谢谢你关于eval()的提示!我会确保避免使用它 :) - Alex
4
一旦你发现JSON.parse()在IE7中无法工作,那么在jQuery中有一种方法可以在所有浏览器中实现它,使用$.parseJSON() - Kevin B
这就是我最终所做的。看看我发布的解决方案。我使用嵌套的$.each语句来获取我要查找的数据。感谢您的帮助! - Alex

19
我成功解决了我的问题。这是我的代码:
复杂的JSON对象:
   {
    "medications":[{
            "aceInhibitors":[{
                "name":"lisinopril",
                "strength":"10 mg Tab",
                "dose":"1 tab",
                "route":"PO",
                "sig":"daily",
                "pillCount":"#90",
                "refills":"Refill 3"
            }],
            "antianginal":[{
                "name":"nitroglycerin",
                "strength":"0.4 mg Sublingual Tab",
                "dose":"1 tab",
                "route":"SL",
                "sig":"q15min PRN",
                "pillCount":"#30",
                "refills":"Refill 1"
            }],
            "anticoagulants":[{
                "name":"warfarin sodium",
                "strength":"3 mg Tab",
                "dose":"1 tab",
                "route":"PO",
                "sig":"daily",
                "pillCount":"#90",
                "refills":"Refill 3"
            }],
            "betaBlocker":[{
                "name":"metoprolol tartrate",
                "strength":"25 mg Tab",
                "dose":"1 tab",
                "route":"PO",
                "sig":"daily",
                "pillCount":"#90",
                "refills":"Refill 3"
            }],
            "diuretic":[{
                "name":"furosemide",
                "strength":"40 mg Tab",
                "dose":"1 tab",
                "route":"PO",
                "sig":"daily",
                "pillCount":"#90",
                "refills":"Refill 3"
            }],
            "mineral":[{
                "name":"potassium chloride ER",
                "strength":"10 mEq Tab",
                "dose":"1 tab",
                "route":"PO",
                "sig":"daily",
                "pillCount":"#90",
                "refills":"Refill 3"
            }]
        }
    ],
    "labs":[{
        "name":"Arterial Blood Gas",
        "time":"Today",
        "location":"Main Hospital Lab"      
        },
        {
        "name":"BMP",
        "time":"Today",
        "location":"Primary Care Clinic"    
        },
        {
        "name":"BNP",
        "time":"3 Weeks",
        "location":"Primary Care Clinic"    
        },
        {
        "name":"BUN",
        "time":"1 Year",
        "location":"Primary Care Clinic"    
        },
        {
        "name":"Cardiac Enzymes",
        "time":"Today",
        "location":"Primary Care Clinic"    
        },
        {
        "name":"CBC",
        "time":"1 Year",
        "location":"Primary Care Clinic"    
        },
        {
        "name":"Creatinine",
        "time":"1 Year",
        "location":"Main Hospital Lab"  
        },
        {
        "name":"Electrolyte Panel",
        "time":"1 Year",
        "location":"Primary Care Clinic"    
        },
        {
        "name":"Glucose",
        "time":"1 Year",
        "location":"Main Hospital Lab"  
        },
        {
        "name":"PT/INR",
        "time":"3 Weeks",
        "location":"Primary Care Clinic"    
        },
        {
        "name":"PTT",
        "time":"3 Weeks",
        "location":"Coumadin Clinic"    
        },
        {
        "name":"TSH",
        "time":"1 Year",
        "location":"Primary Care Clinic"    
        }
    ],
    "imaging":[{
        "name":"Chest X-Ray",
        "time":"Today",
        "location":"Main Hospital Radiology"    
        },
        {
        "name":"Chest X-Ray",
        "time":"Today",
        "location":"Main Hospital Radiology"    
        },
        {
        "name":"Chest X-Ray",
        "time":"Today",
        "location":"Main Hospital Radiology"    
        }
    ]
}

抓取数据并在我的网页上显示的jQuery代码:

$(document).ready(function() {
var items = [];

$.getJSON('labOrders.json', function(json) {
  $.each(json.medications, function(index, orders) {
    $.each(this, function() {
        $.each(this, function() {
            items.push('<div class="row">'+this.name+"\t"+this.strength+"\t"+this.dose+"\t"+this.route+"\t"+this.sig+"\t"+this.pillCount+"\t"+this.refills+'</div>'+"\n");
        });
    });
  });

  $('<div>', {
    "class":'loaded',
    html:items.join('')
  }).appendTo("body");

});

});


13
对我来说,现在评论可能有些晚了;但是我觉得你还在大量使用数组,即使只有一个对象也是如此。例如,您的顶级 medications 属性是一个包含单个对象的数组。除非您真的需要在此处考虑多个药品类型的集合,否则我会完全放弃数组。然后您就可以使用var x = medications.aceInhibitors而不是medications[0].aceInhibitors。 (对我来说,第二个代码段的意思是“我正在获取第一个药物对象的aceInhibitors属性”-这里“第一个”是什么意思?) - Andrzej Doyle
我认为你不需要将med类型的属性放入数组中。实际上,有一种推荐的构建JSON以提高性能的方法。请参阅属性排序 https://google.github.io/styleguide/jsoncstyleguide.xml?showone=Property_Ordering_Example#Property_Ordering_Example - Ronnie Royston

4

请确保遵循JSON的语言定义。在您的第二个示例中,这个部分是:

"labs":[{
    ""
}]

由于对象必须由零个或多个键值对 "a" : "b" 组成,其中 "b" 可以是任何有效的值,因此 { "" } 是无效的。有些解析器可能会自动将 { "" } 解释为 { "" : null },但这不是一个明确定义的情况。
另外,您经常使用嵌套的对象数组 [{}]。我只会在以下情况下这样做:
1. 数组中没有一个好的 "标识符" 字符串来指代每个对象。 2. 有一些明显的理由使得数组比键值对更适合该条目。

Labs只是一个占位符...这只是一个初步的概念。我知道它需要一个值。 - Alex

1

你可以尝试使用这个函数来在嵌套的数组中查找任何对象。

示例

function findTByKeyValue (element, target){
        var found = true;
        for(var key in target) { 
            if (!element.hasOwnProperty(key) || element[key] !== target[key])   { 
                found = false;
                break;
            }
        }
        if(found) {
            return element;
        }
        if(typeof(element) !== "object") { 
            return false;
        }
        for(var index in element) { 
            var result = findTByKeyValue(element[index],target);
            if(result) { 
                return result; 
            }
        } 
    };

findTByKeyValue(problems,{"name":"somethingElse","strength":"500 mg"}) =====> result equal to object associatedDrug#2

0

首先,选择数据结构(xml、json、yaml)通常只涉及可读性/大小问题。例如

Json非常紧凑,但没有人能够轻松阅读它,也很难调试,

Xml非常庞大,但每个人都可以轻松阅读/调试它,

Yaml介于Xml和json之间。

但如果您想要大量使用Javascript并/或者您的软件在浏览器和服务器之间进行大量数据传输,则应该使用Json,因为它是纯Javascript并且非常紧凑。但不要尝试将其编写成字符串,使用库从对象生成所需的代码。

希望这有所帮助。


1
@Alex 举个例子,在 PHP 中创建数组/对象,然后使用 json_encode() 将其转换为有效的 JSON。 - Kevin B
1
在PHP中创建一个对象,然后使用json_encode()方法将其发送或嵌入到您的页面中。该过程称为序列化对象,抱歉我在问题中忘记说了;http://www.itnewb.com/tutorial/Introduction-to-JSON-and-PHP/page3 这里有一个例子。 - gkaykck
9
我认为这很主观... 我发现JSON比XML更容易阅读。 - Felix Kling
我同意。我认为JSON非常容易阅读。XML已经失控了。呵呵 - Alex
XML并不像JSON那样易于人类阅读。 - Channaveer Hakari
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接