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
Insert Query Check If Record Exists - If Not, Insert It
Is PHP's 'Include' a Function or a Statement
Laravel Checking If a Record Exists
Simple PHP Form: Attachment to Email (Code Golf)
Phpmailer: Reply Using Only "Reply To" Address
How to Execute PHP Code Within JavaScript
PHP Remove All Characters Before Specific String
Reflectionexception: Class Classname Does Not Exist - Laravel
How to Create an Empty Array in PHP with Predefined Size
Using Variables in MySQL Update (Php/Mysql)
Can't Install PHPunit via Pear, Requires Pear Installer >= 1.9.2, Can't Upgrade Pear from 1.9.0
PHP How to Retrieve Array Values
PHP Composer Update "Cannot Allocate Memory" Error (Using Laravel 4)
Algorithm to Get All Possible String Combinations from Array Up to Certain Length