PHP - How to sort multidimensional array by Key? - php

I have to sort multidimensional array by key and I need some recomendation how to do it.
I tried using ksort() and other php built-in functions, but none of them helped me.
This is my array, which I want to sort by key:
Array
(
[0] => Array
(
[20190529] => Array
(
[30] => Array
(
[17] => Array
(
[3846] => 0
)
)
)
)
[1] => Array
(
[20190516] => Array
(
[31] => Array
(
[17] => Array
(
[512] => 0
)
)
)
)
)
In that case, keys are 20190529 and 20190516

Working demo.
You can use array_multisort to achieve your requirement.
$keys = [];
foreach($arr as $k => $item){
$keys[] = key($item);
}
array_multisort($keys, SORT_NATURAL, $arr);
array_multisort — Sort multiple or multi-dimensional arrays
SORT_NATURAL - compare items as strings using "natural ordering" like natsort().

I modified my array like that:
Array
(
[0] => Array
(
[DATE] => 20190503
[DEAL] => 30
[IBLOCK] => 18
[AMOUNT] => 2500
[PAYED] => 0
)
[1] => Array
(
[DATE] => 20190516
[DEAL] => 31
[IBLOCK] => 17
[AMOUNT] => 512
[PAYED] => 0
)
)
then I used usort():
function cmp($a, $b) {
return $a['DATE'] - $b['DATE'];
}
usort($mydata, "cmp");
And it did job for me :) but Now I have to modify my array again to return first look.

Related

Most efficient way to sort a multidimensional array (php)

I am looking for the most efficient way to sort a multidimensional array in php.I want to sort the array by the value name in [result][index][kl][0]. What is the fastest way to do this? My array has like 100 elements.
My array looks like this:
Array
(
[jsonrpc] => 2.0
[id] => req-002
[result] => Array
(
[0] => Array
(
[type] => subst
[lsid] => 11
[date] => 20150209
[startTime] => 955
[endTime] => 1040
[kl] => Array
(
[0] => Array
(
[id] => 29
[name] => S12UB
)
)
)
[1] => Array
(
[type] => subst
[lsid] => 11
[date] => 20150209
[startTime] => 1045
[endTime] => 1130
[kl] => Array
(
[0] => Array
(
[id] => 29
[name] => S12UB
)
)
)
Thank you.
Use a user-defined sort function, like usort along with strcmp:
function compareByName($a, $b) {
// the strcmp returns a numeric value above or below 0 depending on the comparison
return strcmp($a['k1'][0]['name'], $b['k1'][0]['name']);
}
Then, assuming your multi-dimensional array is named $array, replace the multi-dimensional array $array['result'] with the newly sorted array:
$array['result'] = usort($array['result'], 'compareByName');
The documentation for the usort and strcmp should be self-explanatory for understanding how the code works above.
$result = uasort($result, function($a, $b) {
return strcmp($a['kl'][0]['name'], $b['kl'][0]['name']);
});

Array format Conversion in PHP

I have got an array which looks like the following:
Array ( [0] => Array ( [id] => 0 ) [1] => Array ( [id] => 0 ) [2] => Array ( [id] => 0 ) [3] => Array ( [id] => 0 ) [4] => Array ( [id] => 0 ) [5] => Array ( [id] => 0 ) [6] => Array ( [id] => 0 ) [7] => Array ( [id] => 0 ) [8] => Array ( [id] => 0 ) [9] => Array ( [id] => 0 ) [10] => Array ( [id] => 0 ) [11] => Array ( [id] => 4 ) [12] => Array ( [id] => 1 ) [13] => Array ( [id] => 2 ) [14] => Array ( [id] => 0 ) [15] => Array ( [id] => 0 ) [16] => Array ( [id] => 5 ) [17] => Array ( [id] => 1 ) )
and I would like to convert it into the following format:
[0,0,0,0,0,0,0,0,0,0,0,4,1,2,0,0,5,1]
How can I achieve this conversion using php?
All the help is appreciated.
PHP >= 5.5.0 needed for array_column() or use the PHP Implementation of array_column():
$result = array_column($array, 'id');
Simplest way: (assuming that you want it to actually output the string [5,6,...,2]
<?php
$ids=array();
foreach($yourArray as $k=>$v){
$ids[] = $v['id'];
}
$resultCsv = implode(',', $ids);
$result = '['.$resultCsv.']';
echo $result
?>
You can use array_map or array_walk:
With array_map:
$new = array_map(function ($value) { return $value['id']; }, $theArray);
print_r($new);
With array_walk:
array_walk($theArray, function (&$value, $key) { $value = $value['id']; };
print_r($theArray);
The main differences between these is that array_map produces a completely new array, and you dont get the key passed to the callback function. array_walk on the other hand works on the array by reference and the callback also gets the key.
Now its unclear to me whether you wanted the array restructured (as i provided solutions for) or if you want it in a specific string format like the [0,1,2,3,...] you provided. If you did want it in a string format all you need to do now is call json_encode on it:
// note if you used array_map pass the variable that holds the result of the call
// (in my example that would be $new); If you used array_walk then pass the same array
// you supplied as the argument to the call (in my exmaple that would be $theArray)
$arrString = json_encode($theArray);
You can process every member of the array and append every currently processed sub-array's member "id" to a new array:
<?php
// code
foreach $array as $member {
$newarray[]=$member["id"];
}
// code
?>

Sort Multi Dimensional Array by its keys from another arrays values

This is an issue I haven't come across before, and there doesn't appear to be a function for this.
I'm trying to sort the following multi dimensional array by its keys
Array (
[hiphop] => Array (
[0] => 2123
[1] => 5683
[2] => 2345
[3] => 4567
)
[rnb] => Array (
[0] => 2123
[1] => 5683
[2] => 2345
[3] => 4567
)
[dubstep] => Array ( )
[reggae] => Array ( )
[trap] => Array ( )
)
From this arrays values
Array (
[0] => hiphop
[1] => dubstep
[2] => reggae
[3] => trap
[4] => rnb
[5] => rnb
)
Has anyone attempted this before or know a workaround?
An explanation would be great as I'm new to multi dimensional arrays
Many thanks in advance if you can help!
The final output would match the value organsiation from the non multi dimensional array like so
Array (
[hiphop] => Array (
[0] => 2123
[1] => 5683
[2] => 2345
[3] => 4567
)
[dubstep] => Array ( )
[reggae] => Array ( )
[trap] => Array ( )
[rnb] => Array (
[0] => 2123
[1] => 5683
[2] => 2345
[3] => 4567
)
)
The easiest Way would be to "flip" the array definining the sorting - then grab the values matching the new keys in the other array:
$s = array ("hiphop","dubstep","reggae","trap","rnb");
$target = array_flip($s);
foreach($target AS $key => &$value){
$value = $array_containing_unsorted_values[$key];
}
Note: does not work if the same value appears twice in the sorting array - but that never should happen, cause does not make sence for a sorting-definition.
Should be way faster than using array_search 2 times within each sorting comparission.
result:
Array
(
[hiphop] => Array
(
[0] => 2123
[1] => 5683
[2] => 2345
[3] => 4567
)
[dubstep] => Array
(
)
[reggae] => Array
(
)
[trap] => Array
(
)
[rnb] => Array
(
[0] => 2123
[1] => 5683
[2] => 2345
[3] => 4567
)
)
You can use uksort for that, which lets you sort by key, based on a user supplied comparison function. Using that function, you can make a function yourself, so you can hide the complex functionality in an easy one.
For instance, you want a function like ksort, only you want to specify an external array of keys, so such a function could look like this:
bool ksort_ext(&$array, $keys)
For the implementation, you can wrap uksort, like so:
function ksort_ext(&$array, $keys)
{
return uksort($array, function($a, $b) use ($keys) {
// Result of callback is based on the position of $a and $b in $keys
return array_search($a, $keys) - array_search($b, $keys);
});
}
Then, you can call it like you would call other sort functions, only with the external array of keys as a second parameter.
$array1 = array(
'hiphop' => array(1,2,3),
'rnb' => array(1,2,3),
'dubstep' => array(1,2,3),
'reggae' => array(1,2,3),
'trap' => array(1,2,3));
$array2 = array('hiphop', 'dubstep', 'reggae', 'trap', 'rnb');
var_dump(ksort_ext($array1, $array2)); // Should return true
var_dump($array1); // Should display the ordered array,

sorting an array dynamically without knowing existing dimensions

I know that ksort() is used to sort array by keys. The max dimension of my array always differs. Sometime 2, sometimes 5, sometime 10 dimensional so how do I use ksort() to do sorting dynamically without knowing how many dimensions exist in it?
Thanks
EXAMPLE ARRAY
[2010] => Array
(
[3] => Array
(
[B] => Array
(
[6] => Array
(
[Patato] =>
)
[C] => Array
(
[Patato] =>
[Zozo] =>
)
)
[A] => Array
(
[F] => Array
(
[Tomato] =>
[Apple] =>
[Kiwi] =>
)
)
[1] => Array
(
[4] => Array
(
[A] => Array
(
[Orange] =>
)
)
If you mean you want to sort recursive:
function deep_ksort(&$arr) {
ksort($arr);
foreach ($arr as &$a) {
if (is_array($a) && !empty($a)) {
deep_ksort($a);
}
}
}
This comes from http://www.php.net/manual/en/function.ksort.php#105399

php sort array by sub-value

here is my array, I think i should be using usort but i have no idea how to get that working.
Array
(
[javascript] => Array
(
[core] => Array
(
[0] => Array
(
[file] => /path/to/file.js
[weight] => 0
)
[1] => Array
(
[file] => /path/to/file2.js
[weight] => 1
)
)
)
)
I would like to sort the index of core by the weight value, other files and weights will be added and sorted after also.
usort($array['javascript']['core'], function($a, $b) {
return $a['weight'] - $b['weight'];
});

Categories