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
Related
I wonder if there is better (faster) way to search for value in multidimensional array than looping through every item.
Lets say i have
$id_to_search = '16819976033';
And array which is pretty big
Array
(
[0] => Array
(
[id] => Array
(
[0] => 16771055710
[1] => 16776555710
[2] => 16819976033
)
[o] => 21566
[p] => 12597.66
)
[1] => Array
(
[id] => Array
(
[0] => 14089762
)
[o] => 12606
[p] => 1747.49
)
etc ...
)
I can find it if i loop through each item and than compare them but its very slow because array is big.
You can use by array_search function in PHP:
$key = array_search($id_to_search, array_column($YourArray, 'id'));
I've an array like below, what I want is to display record having row at the bottom whose "quotes" array is empty.
Array
(
[0] => Array
(
[id] => 0
[regNo] => LHR7171
[quotes] => Array
(
)
)
[1] => Array
(
[id] => 2
[regNo] => YN09 BYY (9)
[quotes] => Array
(
somevalues in array format
)
)
uasort(
$i,
function($value1, $value2) {
return count($value2['quotes']) - count($value1['quotes']);
}
);
And regarding the tags below your question: this has (of course) absolutely nothing to do with SF2 or Twig. This is just plain PHP.
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,
I'm having trouble combining these two arrays so that the keys are kept together. The problem (I think) I'm having is that the arrays don't match in their structures, and the array keys are integers in one and names in the other. I feel like I need to have one array (feel free to correct me) so that I can display the prices coherently on the page, but I can't wrap my head around how to do it. I tried an array_merge, but it looses the indexed tlds sub-array:
$result = array();
foreach($cats[0]['domorder'] as $domorder) {
$result = array_merge($domorder, $prices[0]);
}
Maybe I can somehow (this isn't working either) add a 'price' sub-array that won't be overwritten?
$result = array();
$prc = array();
$prc['price'] = $prices[0];
foreach($prc as $p) {
$result = array_merge($p, $cats[0]['domorder'][0]);
}
Here's basically what I'm working with...my apologies if these are not formatted correctly for questions here.
Array 1, category definitions of hosting/domain name products:
Array
(
[0] => Array
(
[hosting] => Array
(
[0] => vpslinuxin
[1] => resellerhostinglinuxuk
[2] => resellerwindowshostinguk
........etc,etc.........
[34] => hosting
)
[domorder] => Array
(
[0] => Array
(
[dombiz] => Array
(
[0] => biz
)
)
[1] => Array
(
[dominfo] => Array
(
[0] => info
)
)
........etc,etc.........
Array 2, prices associated to the above categorized products:
Array
(
[0] => Array
(
[resellerhostinglinuxuk] => Array
(
[131] => Array
(
[renew] => Array
(
[1] => 43.19
)
[ssl] => 4.79
[add] => Array
(
[1] => 43.19
)
)
........etc,etc.........
[dombiz] => Array
(
[addtransferdomain] => Array
(
[1] => 10.69
)
[restoredomain] => Array
(
[1] => 69.95
)
[addnewdomain] => Array
(
[10] => 10.89
[9] => 10.89
)
........etc,etc.........
Anyone? I feel like this should be a fairly easy merge, but I can't figure out how to make it work.
Edit
Here's an example of how I think it should work:
Array
(
[0] => Array
(
[hosting] => Array
(
[vpslinuxin] => Array
(
[prices] => Array
(
[addons] => Array
(
.......
)
[plans] => Array
(
.......
)
)
)
)
[domorder] => Array
(
[0] => Array
(
[dombiz] => Array
(
[tlds] => Array
(
[0] => biz
)
[prices] => Array
(
[addtransferdomain] => Array
(
.......
)
[restoredomain] => Array
(
.......
)
[addnewdomain] => Array
(
.......
)
[renewdomain] => Array
(
.......
)
)
)
)
)
)
)
thanks for your help Michael but I managed to get it.
I was thinking too hard about it, so after dinner and some relaxing, I decided to simplify what I've been trying. There's no hard/fast rule saying that the two arrays need to be together - ultimately they're going to end up together anyway. So I just appended one to the other, defined by a 'product' and 'price' key:
$result = array();
$result[]['product'] = $cats[0];
$result[]['prices'] = $prices[0];
I have a multi-dimensional array and what i want is in each second degree of array values limit should be set to 4 only. Like i have a array of type:
Array
(
[test2] => Array
(
[0] => Array
(
[application_id] => 405275016
)
[1] => Array
(
[application_id] => 405275016
)
[2] => Array
(
[application_id] => 303198288
)
[3] => Array
(
[application_id] => 303841592
)
)
[test3] => Array
(
[0] => Array
(
[application_id] => 289267216
)
[1] => Array
(
[application_id] => 303198216
)
[2] => Array
(
[application_id] => 405275016
)
[3] => Array
(
[application_id] => 303198288
)
[4] => Array
(
[application_id] => 303841592
)
[5] => Array
(
[application_id] => 311430400
)
[6] => Array
(
[application_id] => 318096216
)
[7] => Array
(
[application_id] => 320256352
)
)
)
and what i want that if the inner arrays value exceed 5 count it should not add any further values to it. i have to format this above array to something like:
Array
(
[test2] => Array
(
[0] => Array
(
[application_id] => 405275016
)
[1] => Array
(
[application_id] => 405275016
)
[2] => Array
(
[application_id] => 303198288
)
[3] => Array
(
[application_id] => 303841592
)
)
[test3] => Array
(
[0] => Array
(
[application_id] => 289267216
)
[1] => Array
(
[application_id] => 303198216
)
[2] => Array
(
[application_id] => 405275016
)
[3] => Array
(
[application_id] => 303198288
)
[4] => Array
(
[application_id] => 303841592
)
)
)
here in second array array last 3 arrays were truncated in order to take only 5 count as a value. I have tried many a methods but none achieved this.
Any idea on how can i achieve this will be highly appreciated ??
or you can use the array_slice function like this:
foreach ($array as $key=>$value)
{
$array[$key] = array_slice($value, 0, 5);
}
$array = array_map(function ($arr) { return array_slice($arr, 0, 5); }, $array);
Note that this uses PHP 5.3+ syntax.
If you actually want an array (or something like it) that cannot hold more than 5 elements, you'll need to implement a custom class (possibly by extending ArrayObject) and/or play around with SplFixedArray.
foreach ($array as $k => $v) { // Loop outer array
for ($i = 5; isset($array[$k][$i]); $i++) { // Loop inner array, starting at element #5
unset($array[$k][$i]); // unset all elements >=5
}
}
PHP has no ready functionality for this behavior, you'll have to make your own function for adding values to the array to achieve this.
Ex:
function array_add_value($array, $value) {
if(count($array) < 5) {
$array[] = $value;
}
}
If you wish to manipulate an existing array that already has too many elements, you will have to make a similar function for that
Ex:
function fix_array($array) {
if(count($array) > 5) {
for($i=4;$i<count($array);$i++) {
unset($array[$i]);
}
}
}