Are PHP Associative Arrays Ordered

Are PHP Associative Arrays ordered?

PHP associative arrays (as well as numeric arrays) are ordered, and PHP supplies various functions to deal with the array key ordering like ksort(), uksort(), and krsort()

Further, PHP allows you to declare arrays with numeric keys out of order:

$a = array(3 => 'three', 1 => 'one', 2 => 'two');
print_r($a);

Array
(
[3] => three
[1] => one
[2] => two
)
// Sort into numeric order
ksort($a);
print_r($a);
Array
(
[1] => one
[2] => two
[3] => three
)

From the documentation:

An array in PHP is actually an ordered map. A map is a type that associates values to keys. This type is optimized for several different uses; it can be treated as an array, list (vector), hash table (an implementation of a map), dictionary, collection, stack, queue, and probably more. As array values can be other arrays, trees and multidimensional arrays are also possible.

Does php conserve order in associative array?

Yes, php arrays have an implicit order. Use reset, next, prev and current - or just a foreach loop - to inspect it.

How does PHP keep track of order in an associative array?

How are associative arrays implemented in PHP? might give you some insight.

It seems that PHP arrays are essentially hash tables, so the order of the array will stay the same until you reorder it (e.g. by sorting the array).

EDIT: It appears this is getting downvoted, allow me to explicitly include the sources I linked to in the comment below here...

  • "PHP associative arrays are in fact an implementation of HashTables", from
    How is the PHP array implemented on the C level?

  • Also from that source: "The PHP array is a chained hash table (lookup of O(c) and O(n) on key collisions) that allows for int and string keys. It uses 2 different hashing algorithms to fit the two types into the same hash key space."

  • "Everything is a HashTable" from http://nikic.github.io/2012/03/28/Understanding-PHPs-internal-array-implementation.html

Is the order of an associative array guaranteed in PHP?

From the PHP Manual

An array in PHP is actually an ordered
map. A map is a type that associates
values to keys. This type is optimized
for several different uses; it can be
treated as an array, list (vector),
hash table (an implementation of a
map), dictionary, collection, stack,
queue, and probably more.

and

Arrays are ordered. The order can be
changed using various sorting
functions.

So you can be certain (at least currently) that the order will be maintained. I would be very surprised if this behaviour were to change because it is clearly stated and because of this there will be a huge amount of code that relies on it.

How to sort an array of associative arrays by value of a given key in PHP?

You are right, the function you're looking for is array_multisort().

Here's an example taken straight from the manual and adapted to your case:

$price = array();
foreach ($inventory as $key => $row)
{
$price[$key] = $row['price'];
}
array_multisort($price, SORT_DESC, $inventory);

As of PHP 5.5.0 you can use array_column() instead of that foreach:

$price = array_column($inventory, 'price');

array_multisort($price, SORT_DESC, $inventory);

PHP: re order associative array

If you mean to swap two values you could make a function like this:

function array_swap($key1, $key2, $array) {
$newArray = array ();
foreach ($array as $key => $value) {
if ($key == $key1) {
$newArray[$key2] = $array[$key2];
} elseif ($key == $key2) {
$newArray[$key1] = $array[$key1];
} else {
$newArray[$key] = $value;
}
}
return $newArray;
}

Preserving order of an associative PHP array while passing it to javascript through ajax

The problem with using hashmaps is that they don't actually specify order. Though, in PHP, an array is actually an ordered hashmap, so it does. Once you translate that into an object in Javascript, the order is no longer preserved. The only way to guarantee order in Javascript is to use an array.

So in PHP this works as expected and preserves order.

$arr = [4 => "I'm first", 1 => "I'm second", 3 => "I'm third"];

foreach($arr as $value) {
echo $value, "\n";
}

Which gives us


I'm first
I'm second
I'm third

But encode that to Javascript Object Notation (i.e. JSON) and you get an object, because in Javascript arrays don't have keys, they have indexes.

echo json_encode($arr);

Gives us...


{"4":"I'm first","1":"I'm second","3":"I'm third"}

If you tried to do the same in Javascript with this object you might not get the same order

var obj = {"4":"I'm first","1":"I'm second","3":"I'm third"};

var s = "";
for(var x in obj) {
s += + obj[x] + "\n";
}

document.write("<pre>" + s + "</pre>");

This might give you something more like...


I'm second
I'm third
I'm first

So the only way to fix that is to use an array...

json_encode(array_values($arr));

Now this gives us...


["I'm first","I'm second","I'm third"]

And the order is maintained.

However, if you want to preserve the keys as well, you'll have to create an array of objects.

$json = [];
foreach($arr as $key => $value) {
$json[] = [$key => $value];
}

echo json_encode($json);

Now you get...


[{"4":"I'm first"},{"1":"I'm second"},{"3":"I'm third"}]

Which in javascript, works perfectly as expected...

for(var x in obj) {
for(var n in obj[x]) {
obj[x][n]; // now you can both maintain order and have access to the key
}
}

Why does Symfony provide an OrderedHashMap

Of course PHP's array is an ordered-map.

But Symfony's OrderedHashMap has some different behaviors (say, features) from PHP's array.

OrderedHashMap supports concurrent modification during iteration. That means that you can insert and remove elements from within a foreach loop and the iterator will reflect those changes accordingly. But array in the iteration is a copied one (Copy-On-Write), any modification is not reflected in the loop.

$map = new OrderedHashMap();
$map[1] = 1;
$map[2] = 2;
$map[3] = 3;

foreach ($map as $index => $value) {
echo "$index: $value\n"
if (1 === $index) {
$map[1] = 4;
$map[] = 5;
}
}

You will get different output if you are using array. In the iteration of an array the loop won't see the number 5.

About "Why?": Search it in Symfony's codebase. There is only one place to use the OrderedHashMap, which is used to store a form's children. It's used by new InheritDataAwareIterator($this->children) to iterate. So I think the answer is to help to process the form's children.

And thanks to @fishbone:

So the benefit is not the ordering but the ability to modify it in loops.

How to sort a php associative array to a specific order?

Easy- Just use the arraySort as the assoc key and get the corresponding array / value from the original array,

<?php

$arraySort = [
"break",
"period1",
"period2",
"period3",
"lunch",
"period4",
"period5",
"period6",
"finish"
];

$final_array = [];

foreach($arraySort as $arraySo){
$final_array[$arraySo] = isset($aData[$arraySo]) ? $aData[$arraySo] : [];
}

print_r($final_array);

Output:- https://3v4l.org/4LXvS



Related Topics



Leave a reply



Submit