Sort php sub array based on sub key - php

Here is a snippet of my array that is used in php 5.3.x :
$arr[$category][$item][$attr_qty] = 3;
$arr[$category][$item][$attr_price] = 12.00;
$category are arbitrary integers, as are $item, as are $attr_qty and $attr_price.
Is there a quick way of sorting, by $attr_qty, the items in each category?
Using integers makes the code easier, but I get the feeling I will have to use associative arrays.

You can use usort which allows you to specify a custom sorting function
usort($arr, 'customSortFunction');
function customSortFunction($a, $b)
{
if ($a['item']['attr_qty'] > $b['item']['attr_qty']) return 1; //First element is bigger
elseif ($a['item']['attr_qty'] < $b['item']['attr_qty']) return -1; //Second element is bigger
else return 0; //Both are equal
}

Related

Sorting a two dimensions array using second level values

I have a 2 dimensions array and need to sort it according to some of the second dimension values.
I tried using uksort, but it doesn't work:
$arr = array();
$arr[] = array('name'=>'test1', 'age'=>25);
$arr[] = array('name'=>'test2', 'age'=>22);
$arr[] = array('name'=>'test3', 'age'=>23);
$arr[] = array('name'=>'test4', 'age'=>29);
uksort($arr, "cmp");
print_r($arr);
function cmp($a, $b) {
if ($a['age']==$b['age']) return 0;
return ($a['age'] < $b['age']) ? -1 : 1;
}
Can anyone spot what am I doing wrong?
I think you are looking for uasort().
uksort() will order your array by keys, but you want to sort the arrays by their value.
uksort
Sort an array by keys using a user-defined comparison function
Sorting array by keys means that you take value of a key (in your case it is the same string age for all subarrays). And you sort by value.
So usort is enough - fiddle.

PHP Sort associative array

I have an associative array like this one:
$teams_name_points = array();
$name1 = "name1";
$name2 = "name2";
$teams_name_points[$name1] = 1;
$teams_name_points[$name2] = 2;
I want to sort this array by the key values, currently it's sorted alphabetically by the key.
I tried to implement my own sorting function, but I do not quite understand how it works.
usort($teams_name_points, 'cmp');
function cmp(array $a, array $b){
if ($a['foo'] < $b['foo']) {
return -1;
} else if ($a['foo'] > $b['foo']) {
return 1;
} else {
return 0;
}
}
How do I make the compare method work with my array?
use asort() to sort your array.
http://php.net/manual/en/function.asort.php
This function sorts an array such that array indices maintain their correlation with the array elements they are associated with. This is used mainly when sorting associative arrays where the actual element order is significant.
$teams_name_points = array();
$name1 = "name1";
$name2 = "name2";
$teams_name_points[$name1] = 2;
$teams_name_points[$name2] = 1;
print_r($teams_name_points);
asort($teams_name_points); // sort by value low to high
print_r($teams_name_points);
arsort($teams_name_points); // sort by value high to low
print_r($teams_name_points);
Simply enough, as per the manual, you'll only want to accept the values of the arrays as the arguments to cmp().
E.g.
cmp($earlier_array_value, $later_array_value){
...
}
Also, of course, be aware that usort() is only warranted when you're running a comparison that is custom and not-numerically-straightforward. Simple comparisons by > or < can be more easily done with existing native sort functions.

Best way to sort 2d Array Php

I'm reading from a text file that has 2 columns. name,rank So it looks like this:
quxerm,6
brock,5
chris,15
So the 2d array looks like [0][0] = quxerm and [0][1]=6 [1][0] = brock [1][1]=5
I already have them into a 2d array like I showed above.
I need to sort these values in descending order by the integer column. How can I sort this?
#CBergau's answer is almost perfect but the order will be ascending instead of descending.
To get it descending just switch the return values of the compare function which is called by usort. See http://www.php.net/manual/en/function.usort.php for more information.
function cmp(array $a, array $b) {
return ($a[1] < $b[1]) ? 1 : -1;
}
usort($arr, 'cmp');
Example: http://codepad.org/QRTQLxTh
You could also extend the compare function for example to order ascending by name when the rank is the same by using strcmp. See http://www.php.net//manual/en/function.strcmp.php for more information.
function cmp(array $a, array $b) {
if ($a[1] == $b[1]) {
return strcmp($a[0], $b[0]);
}
return ($a[1] < $b[1]) ? 1 : -1;
}
Example: http://codepad.org/SeRTE3Ym
Note: I've not enough reputation yet to just comment on #CBergau's answer.
Use map instead, and then you can use all the functions relatives to maps like this.
take the array as arr[i][j].
try comparing only by changing the values of i.
for(int i=0;i<3;i++)
for(int k=1;k<3;k++)
if(arr[i][1]>arr[k][1])
max=i
and you can retrieve max by :-
arr[max][0]//name of max
arr[max][1]//value of max
$sorted = array();
foreach($yourArray as $a){
$sorted[$a[1]] = $a[0];
}
ksort($sorted);
vardump($sorted);
This should sort by the integer column:
usort(
$data,
function ($arrayOne, $arrayTwo) {
return ($arrayOne[1] < $arrayTwo[1]) ? -1 : 1;
}
);
If there are no duplicate names, you can simply assign the rank for the key (name), and sort that array while preserving keys.
$data["quxerm"] = 6;
$data["brock"] = 5;
$data["chris"] = 15;
asort($data, SORT_NUMERIC);

Sorting a multidimensional array by numeric value of a dimension that's not the first

I am creating a search capability for a forum program I'm building. At one point I have an array called searchResults which is numeric and contains 'score' as one of its dimensions (others are 'timeStarted', 'authorUID', and 'TID')
So, this array is in disarray at this point and I need to organize it to where $searchResults[1] will be the highest 'score' and [2] will have the second highest, etc. I looked at array_multisort on php.net but got rapidly lost in how it worked. So how would I sort $searchResults in numeric order (rearrange the keys) descending with a descending order of a further dimension 'sort' as the sorting mechanism? There really isn't any code to go with it but if you need a layout of how the array looks, here you go:
$searchResults:
[1] - ['timeStarted']
['authorUID']
['score'] <- Need to sort first dimension by this value descending
['TID']
etc.
Thanks for any help.
usort allows sorting by any specified comparison function
$cmp = function($a,$b) {return $b['score'] - $a['score'];};
usort($searchResults, $cmp);
In this case, $cmp is a function that compares two elements $a and $b of $searchResults based on value of ['score']. $cmp returns 0 for equality, negative val if $a['score'] is greater, positive val if $b['score'] is greater. It would normally be the other way around, but a descending sorting order is desired.
The function you want is usort. Look at example #2:
<?php
function cmp($a, $b)
{
return strcmp($a["fruit"], $b["fruit"]);
}
$fruits[0]["fruit"] = "lemons";
$fruits[1]["fruit"] = "apples";
$fruits[2]["fruit"] = "grapes";
usort($fruits, "cmp");
while (list($key, $value) = each($fruits)) {
echo "\$fruits[$key]: " . $value["fruit"] . "\n";
}
?>
The output:
$fruits[0]: apples
$fruits[1]: grapes
$fruits[2]: lemons

PHP sort 2d array by index (non-associative)

This code does not run properly, but it suggests what I am trying to do:
function sort_2d_by_index($a,$i) {
function cmp($x, $y) {
// Nested function, can't find $i
// (global $i defeats the purpose of passing an arg)
if ($x[$i] == $y[$i]) { return 0; }
return ($x[$i] < $y[$i]) ? -1 : 1;
}
usort($a,"cmp");
return $a;
}
There HAS to be a much better way to do this. I've been examining ksort(), multisort(), and all sorts of sorts until I'm sort of tired trying to sort it all out.
The situation is this: I've got a 2-d array...
array(
array(3,5,7),
array(2,6,8),
array(1,4,9)
);
...and I want to sort by a column index. Say, column [1], would give this result:
array(
array(1,4,9),
array(3,5,7),
array(2,6,8)
);
Does someone have a link (I'm sure this has been asked before), or could someone say "you need foosort, definitely". Thanks very much.
In the documentation of array_multisort it is mentioned that it can be used for this kind of thing.
You can't avoid creating an array that consists of only one column:
$sort_column = array();
foreach ($a as $row)
$sort_column []= $row[1]; // 1 = your example
array_multisort($sort_column, $a);
This sorts both arrays synchronously so that afterwards your whole array is sorted in the same order as the $sort_column array is.
As of PHP 5.3 you can use a closure (pass $i into the function) by defining your cmp function like this:
$cmp = function($x, $y) use ($i) { ... };
You can use use to access $i:
function cmp($x, $y) use ($i) {
// $i now available
if ($x[$i] == $y[$i]) { return 0; }
return ($x[$i] < $y[$i]) ? -1 : 1;
}
http://www.php.net/manual/en/function.sort.php#99419
phpdotnet at m4tt dot co dot uk
Simple function to sort an array by a specific key. Maintains index association.

Categories