javascript json_encode 不保留顺序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20912492/
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-27 19:36:01  来源:igfitidea点击:

json_encode not preserving order

javascriptphpjson

提问by croppio.com

I have a multi dimensional array, in PHP:

我在 PHP 中有一个多维数组:

Array
(
[1] => Array
    (
        [19] => Array
            (                    
                [type] => 2
            )            
        [6] => Array
            (                    
                [type] => 4
            )
        [12] => Array
            (                    
                [type] => 3
            )
    )

)

When i json_encode this array in javascript via:

当我通过以下方式在 javascript 中 json_encode 这个数组时:

 var jsonArray = <?php echo json_encode($above_array); ?>;

i get:

我得到:

 Object
 (
 [1] => Object
 (
    [6] => Object
        (                    
            [type] => 2
        )
    [12] => Object
        (                    
            [type] => 4
        )
    [19] => Object
        (                    
            [type] => 3
        )
)

)

I want to preserve the first order and not the second one by id.

我想通过 id 保留第一个订单而不是第二个订单。

回答by AlexM

There's a question on StackOverflow Does JavaScript Guarantee Object Property Order?In short, the answer is no, it doesn't. So when converting a PHP array to a Javascript object, the key order will not be preserved.

StackOverflow 上有个问题 JavaScript 是否保证对象属性顺序?简而言之,答案是否定的,它没有。因此,当将 PHP 数组转换为 Javascript 对象时,不会保留键顺序。

The major difference between arrays in PHP and Javascript is that the latter can hold only sequential integer keys starting from zero. So it's not always possible to convert a PHP array to a Javascript array. Let's look at a few examples:

PHP 和 Javascript 中的数组之间的主要区别在于后者只能保存从零开始的连续整数键。因此,并非总是可以将 PHP 数组转换为 Javascript 数组。让我们看几个例子:

// example 1
echo json_encode(array(0 => 'a', 1 => 'b')) // outputs ["a","b"]

// example 2
echo json_encode(array(0 => 'a', 3 => 'b')) // outputs {"0":"a","3":"b"}

// example 3
echo json_encode(array(3 => 'b', 0 => 'a')) // outputs {"3":"b","0":"a"}, but in Javascript the key order will be the same as in example 2
  1. In the first example, json_encodeconverts a PHP array into an identical Javascript array.
  2. In the second example, it converts to an object, because the keys order is not sequential.
  3. In the third example, it also converts to an object. But in Javascript, the objects 2 and 3 will be the same, with the same key order, even though the keys are listed in a different order. So it's not json_encodefunction that is not preserving the key order, but Javascript itself.
  1. 在第一个示例中,json_encode将 PHP 数组转换为相同的 Javascript 数组。
  2. 在第二个示例中,它转换为对象,因为键顺序不是顺序的。
  3. 在第三个示例中,它也转换为对象。但是在 Javascript 中,对象 2 和 3 将是相同的,具有相同的键顺序,即使键以不同的顺序列出。因此json_encode,不保留键顺序的不是函数,而是 Javascript 本身。

Returning to our question: how to pass a PHP array to Javascript preserving the key order? One approach is to wrap PHP key-value pairs into arrays:

回到我们的问题:如何将 PHP 数组传递给 Javascript 并保留键顺序?一种方法是将 PHP 键值对包装到数组中:

// original array:
array(
    3 => 'b', 
    0 => 'a'
)

// must be converted to:
array(
    array(3, 'b'),
    array(0, 'a')
)

Then json_encodewill result in the following Javascript array:

然后json_encode将产生以下 Javascript 数组:

[
  [3,"b"],
  [0,"a"]
]

And the last part is iterating through such an array in Javascript:

最后一部分是在 Javascript 中遍历这样的数组:

var php_encoded_array = [
  [3,"b"],
  [0,"a"]
];

for (var i=0; i < php_encoded_array.length; i++) {
  var rec = php_encoded_array[i],
      key = rec[0],
      value = rec[1];

  console.log(key + ': ' + value);
}
// It will output:
// 3: b
// 0: a
// Which is the exact same order as in the PHP array

This approach is also compatible with non-integer keys.

这种方法也与非整数键兼容。

Here's the code (suggested by pr1001in a similar question) for converting an array on the PHP side. It will work for one-dimensional arrays.

这是用于在 PHP 端转换数组的代码(由pr1001在类似问题中建议)。它适用于一维数组。

array_map(
    function($key, $value) { return array($key, $value); },
    array_keys($data),
    array_values($data)
)

And here's a recursive function implementation for multi-dimensional arrays:

这是多维数组的递归函数实现:

function array_preserve_js_order(array $data) {
    return array_map(
        function($key, $value) {
            if (is_array($value)) {
                $value = array_preserve_js_order($value);
            }
            return array($key, $value);
        },
        array_keys($data),
        array_values($data)
    );
}

回答by Rocket Hazmat

The problem is that in JavaScript only arrays are ordered, objects are not.

问题是在 JavaScript 中只有数组是有序的,对象不是。

If you had something like:

如果你有这样的事情:

array(
    array(
        'type' => 2
        'id' => 6
    ),
    array(
        'type' => 4
        'id' => 12
    ),
    array(
        'type' => 3
        'id' => 19
    )
)

Then in your JavaScript you'd have an array of objects, and that array would retain its order.

然后在您的 JavaScript 中,您将拥有一个对象数组,该数组将保留其顺序。

The reason it's out of order is because your array's index didn't start at 0, the keys were not in order and there were gaps in the keys. So, when encoded, PHP turned it into an object instead of an array.

它乱序的原因是因为您的数组的索引不是从 0 开始的,键没有按顺序排列并且键中有间隙。因此,在编码时,PHP 将其转换为对象而不是数组。

回答by Felix Jr

To preserve the order of PHP array, use array_values()function.

要保留 PHP 数组的顺序,请使用array_values()函数。

<?php $php_array = array_values($php_array); ?>
var jsonArray = JSON.parse('<?php echo json_encode($php_array); ?>');