У меня многомерный массив, в PHP:
Array ( [1] => Array ( [19] => Array ( [type] => 2 ) [6] => Array ( [type] => 4 ) [12] => Array ( [type] => 3 ) ) )
Когда i json_encode этот массив в javascript через:
var jsonArray = <?php echo json_encode($above_array); ?>;
я получил:
Object ( [1] => Object ( [6] => Object ( [type] => 2 ) [12] => Object ( [type] => 4 ) [19] => Object ( [type] => 3 ) ) )
Я хочу сохранить первый, а не второй идентификатор.
Возникает вопрос о том, что StackOverflow хранит заказ на объект гарантии JavaScript? Короче говоря, ответ – нет, это не так. Поэтому при преобразовании массива PHP в объект Javascript порядок ключей не сохраняется.
Основное различие между массивами в 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
json_encode
преобразует массив PHP в идентичный массив Javascript. json_encode
которая не сохраняет порядок клавиш, а сам Javascript. Возвращаясь к нашему вопросу: как передать массив PHP в Javascript, сохраняя порядок ключей? Один из подходов состоит в том, чтобы привязать пары ключ-значение PHP к массивам:
// original array: array( 3 => 'b', 0 => 'a' ) // must be converted to: array( array(3, 'b'), array(0, 'a') )
Тогда json_encode
приведет к следующему массиву Javascript:
[ [3,"b"], [0,"a"] ]
И последняя часть выполняет итерацию через такой массив в 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
Этот подход также совместим с нецелыми ключами.
Вот код (предложенный pr1001 в аналогичном вопросе) для преобразования массива на стороне PHP. Он будет работать для одномерных массивов.
array_map( function($key, $value) { return array($key, $value); }, array_keys($data), array_values($data) )
И вот реализация рекурсивной функции для многомерных массивов:
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) ); }
Проблема в том, что в JavaScript упорядочены только массивы, объекты – нет.
Если у вас есть что-то вроде:
array( array( 'type' => 2 'id' => 6 ), array( 'type' => 4 'id' => 12 ), array( 'type' => 3 'id' => 19 ) )
Тогда в вашем JavaScript у вас будет массив объектов, и этот массив сохранит свой порядок.
Причина, по которой это не в порядке, состоит в том, что индекс вашего массива не начинался с 0, ключи были не в порядке, и в ключах были пробелы. Итак, при кодировании PHP превратил его в объект вместо массива.