在解析JSON字符串后,保持对象的顺序

时间:2015-08-14 08:58:13

标签: javascript json

我从API函数收到以下JSON字符串。

"Inbound": {
    "callRelatedFields": ["ANI",
    "DNIS"],
    "objects": {
        "Contact": [{
            "displayName": "Name",
            "apiName": "Name"
        },
        {
            "displayName": "Email",
            "apiName": "Email"
        }],
        "Account": [{
            "displayName": "Account Name",
            "apiName": "Name"
        },
        {
            "displayName": "Phone",
            "apiName": "Phone"
        },
        {
            "displayName": "Fax",
            "apiName": "Fax"
        }],
        "cnx__Phone__c": [{
            "displayName": "Phone Name",
            "apiName": "Name"
        },
        {
            "displayName": "Phone Number Line 1",
            "apiName": "cnx__Phone_Number_Line_1__c"
        },
        {
            "displayName": "Phone Number Line 2",
            "apiName": "cnx__Phone_Number_Line_2__c"
        },
        {
            "displayName": "Type",
            "apiName": "cnx__Type__c"
        },
        {
            "displayName": "Location",
            "apiName": "cnx__Location__c"
        },
        {
            "displayName": "Call Manager",
            "apiName": "cnx__Call_Manager__c"
        },
        {
            "displayName": "Mac Address",
            "apiName": "cnx__Mac_Address__c"
        }]
    },
    "screenPopSettings": {
        "screenPopsOpenWithin": "ExistingWindow",
        "SingleMatch": {
            "screenPopType": "PopToEntity"
        },
        "NoMatch": {
            "screenPopType": "DoNotPop"
        },
        "MultipleMatches": {
            "screenPopType": "DoNotPop"
        }
    }
}

"objects"内对象的顺序很重要! 但是当我用JSON.parse解析这个JSON字符串时,这些对象的顺序就会丢失。

有没有什么好方法可以在解析这些对象后保持这些对象的顺序。

我试图操纵字符串并将整个"objects"转换为数组,但结果变得过于复杂和笨拙。

6 个答案:

答案 0 :(得分:5)

我怀疑让你认为密钥改变顺序的东西是Chrome devtools显示对象,其按键按字母顺序排序。然而,如果您使用Object.keys()或等效的JS手动迭代密钥,您会发现它们按照在JSON字符串中定义的顺序出现。

Screenshot from Chrome devtools

以下是Object.keys()的等效JS:

function objectKeys(obj) {
    var keys = [];
    if (!obj) return keys;
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            keys.push(key);
        }
    }
}

当我用解析对象的objects部分调用它时,我得到以下数组:

["Contact", "Account", "cnx__Phone__c"]

答案 1 :(得分:3)

不幸的是object properties are unordered in JavaScript所以你不应该依赖于能够以特定的顺序迭代它们。

我建议按照您需要的顺序按名称访问属性,而不是仅仅迭代列表。

答案 2 :(得分:2)

根据JSON standard,对象是无序的。因此,如果您关心订单"Contact", "Account", "cnx__Phone__c",请将它们放入数组([])。

也许将属性名称本身放在.objects本身旁边的数组中就足够了,这样您仍然可以通过名称访问它们。许多结构都是有效的解决方案。

答案 3 :(得分:1)

此解决方案仅在属性和数据不包含以下字符之一时才有效:{}:

也许您将花括号替换为方括号,将":替换为#",。之后,您可以对JSON字符串进行解析,并将所有对象替换为数组。读数是:第一个值是属性(在末尾标记为#),第二个值是值。

要改进替代机制,特别是替换有时可能错误的":,以及搜索大括号。

var json = '{"Inbound":{"callRelatedFields":["ANI","DNIS"],"objects":{"Contact":[{"displayName":"Name","apiName":"Name"},{"displayName":"Email","apiName":"Email"}],"Account":[{"displayName":"Account Name","apiName":"Name"},{"displayName":"Phone","apiName":"Phone"},{"displayName":"Fax","apiName":"Fax"}],"cnx__Phone__c":[{"displayName":"Phone Name","apiName":"Name"},{"displayName":"Phone Number Line 1","apiName":"cnx__Phone_Number_Line_1__c"},{"displayName":"Phone Number Line 2","apiName":"cnx__Phone_Number_Line_2__c"},{"displayName":"Type","apiName":"cnx__Type__c"},{"displayName":"Location","apiName":"cnx__Location__c"},{"displayName":"Call Manager","apiName":"cnx__Call_Manager__c"},{"displayName":"Mac Address","apiName":"cnx__Mac_Address__c"}]},"screenPopSettings":{"screenPopsOpenWithin":"ExistingWindow","SingleMatch":{"screenPopType":"PopToEntity"},"NoMatch":{"screenPopType":"DoNotPop"},"MultipleMatches":{"screenPopType":"DoNotPop"}}}}';
json = json.replace(/{/g, '[').replace(/}/g, ']').replace(/"\:/g, '#",');
json = JSON.parse(json);
document.write('<pre>' + JSON.stringify(json, 0, 4) + '</pre>');

答案 4 :(得分:0)

@GregL是正确的,JSON解析是按字母顺序或以数字升序排列的,要保持该顺序,您将需要一个递增的数字逻辑,例如:

var position_in_array = 0
var name = 'screenPopSettings'

object[`${position_in_array}${name}`] = value

position_in_array += 1

答案 5 :(得分:0)

parseJson以对象形式返回数据,并且对象没有索引。因此,如果要保留数组索引,则应定义数据数组的自定义索引。

示例:

$arr[0] = array(
'Contact'=>array(
'key1'=>'val',
)
); 
$arr[1] = array(
'Account'=>array(
'key1'=>'val',
)
); 

它将按照parseJson函数调用之前最初定义的数组索引生成输出。