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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32006162/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 14:43:48  来源:igfitidea点击:

Keep order of objects inside a JSON String after they are parsed

javascriptjson

提问by Praind

I receive the following JSON string from an API function.

我从 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"
        }
    }
}

The order of the objects inside "objects"is important! But when i parse this JSON string with JSON.parse, the order of those objects is lost.

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

Is there any good way to keep the order of those objects after they are parsed.

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

I tried to manipulate the string and convert the whole "objects"into an array, but this turned out to become way too complicated and hacky.

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

回答by GregL

I have a suspicion that the thing that makes you think the keys have changed order is that Chrome devtools show objects with their keys sorted in alphabetical order. Whereas if you use Object.keys()or the equivalent JS to manually iterate through the keys, you will find they come out in the order they were defined in the JSON string.

我怀疑让您认为键已更改顺序的事情是 Chrome 开发工具显示对象的键按字母顺序排序。而如果您使用Object.keys()JS 或等效的 JS 手动遍历键,您会发现它们按照它们在 JSON 字符串中定义的顺序出现。

Screenshot from Chrome devtools

Chrome devtools 的截图

Here is the equivalent JS for Object.keys():

这是等效的 JS Object.keys()

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

When I call this with the objectspart of the parsed object I get the following array:

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

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

回答by codebox

Unfortunately object properties are unordered in JavaScriptso you shouldn't rely on being able to iterate over them in a particular sequence.

不幸的是,JavaScript 中的对象属性是无序的,因此您不应该依赖于能够以特定的顺序迭代它们。

I would suggest accessing the properties by name in the order you need them, rather than just iterating over the list.

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

回答by Bergi

As per the JSON standard, an object is unordered. So if you care about the order "Contact", "Account", "cnx__Phone__c", put them in an array ([]).

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

Maybe it's enough to put the property names themselves in an array next to the .objectsthemselves, so that you still can access them by their names. Many structures are valid solutions.

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

回答by Nina Scholz

This solution works only if the properties and the data does not contain one of these characters: {, }and :.

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

Maybe you replace the curly brackets to square brackets and ":to #",. After that, you can the JSON string parse and get all objects replaced by arrays. The reading is: first value is the property (marked with #at the end) and the second value is the value.

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

The replacement machanism shuld be improved, in particular the replacement of ":, which can sometimes be wrong, and the search of the curly brackets.

应该改进替换机制,特别是替换":有时会出错的 ,以及大括号的搜索。

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

回答by Valter

@GregL is right the JSON parsed came in alphabetic or in case of a number in ascending order and to keep the order you'll need an incremented number logic like:

@GregL 是正确的,解析的 JSON 是按字母顺序排列的,或者在数字按升序排列的情况下,为了保持顺序,您需要一个递增的数字逻辑,例如:

var position_in_array = 0
var name = 'screenPopSettings'

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

position_in_array += 1

回答by Reema Parakh

The parseJson returns data in object form and object doesn't has index. So we should define custom index of data array, if we want to keep the array index.

parseJson 以对象形式返回数据,对象没有索引。所以我们应该定义数据数组的自定义索引,如果我们想保留数组索引。

Example:

例子:

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

It will produce the output as per the array index originally defined before parseJson function call.

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