Sort array with the highest points - php

How do I sort an array with the highest points?
Example:
$sale = array();
Array
(
[UserA] => Array
(
[unsuccessful] => 0
[Points] => 31
[procesing] => 4
)
[UserB] => Array
(
[unsuccessful] => 4
[Points] => 200
[procesing] => 1
)
[UserC] => Array
(
[unsuccessful] => 3
[Points] => 150
[procesing] => 55
)
)
Sort by points, it should be in order: UserB, UserC, UserA

uasort($array, function($a, $b) {
return $b['Points'] - $a['Points'];
});
The uasort() and usort() functions take a callback that should specify exactly what makes one item greater or lower than another item. If this function returns 0, then the items are equal. If it returns a positive number, then the second item is greater than the first item. Else, the first item is greater than the second.
The difference between uasort() and usort() is that uasort() also keeps the keys, while usort() does not. Also take a look at the comparison of array sorting functions to find out about all the other ways you can sort arrays.

You can use the php function usort to provide your own custom sorting logic. See http://www.php.net/manual/en/function.usort.php

You may find USort helpful:
http://php.net/manual/en/function.usort.php
Also this other article on SO.
Sort multi-dimensional array with usort

Related

sorting array based on child array[0] (unix) value

I need an array sorted by Unix timestamp values. I attempted to use both ksort and krsort before realising that occasionally the timestamp values might be the same (and you cannot have duplicate keys in arrays).
Here's an example array I may be faced with:
$array = array(
[
"unix" => 1556547761, // notice the two duplicate unix values
"random" => 4
],
[
"unix" => 1556547761,
"random" => 2
],
[
"unix" => 1556547769,
"random" => 5
],
[
"unix" => 1556547765, // this should be in the 3rd position
"random" => 9
]
);
So what I'm trying to do is sort them all based on each child arrays unix value, however I cannot figure out how to do so. I have tried countless insane ways (including all other sort functions and many, many for loops) to figure it out - but to no avail.
All help is appreciated.
You can use usort which sort your array by given function
Define function as:
function cmpByUnix($a, $b) {
return $a["unix"] - $b["unix"];
}
And use with: usort($array, "cmpByUnix");
Live example: 3v4l
Notice you can also use asort($array); but this will compare also the "random" field and keep the key - if this what you need then look at Mangesh answer
array_multisort() — Sort multiple or multi-dimensional arrays
array_columns() — Return the values from a single column in the input array
You can use array_multisort() and array_column(), then provide your desired sort order (SORT_ASC or SORT_DESC).
array_multisort(array_column($array, "unix"), SORT_ASC, $array);
Explanation:
In array_multisort(), arrays are sorted by the first array given. You can see we are using array_column($array, "unix"), which means that the second parameter is the order of sorting (ascending or descending) and the third parameter is the original array.
This is the result of array_column($array, "unix"):
Array(
[0] => 1556547761
[1] => 1556547761
[2] => 1556547765
[3] => 1556547769
)
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.
Note:If two members compare as equal, their relative order in the sorted array is undefined.
Refer : https://www.php.net/manual/en/function.asort.php
asort($array);
echo "<pre>";
print_r($array);
echo "</pre>";
It will give you the output as
Array
(
[1] => Array
(
[unix] => 1556547761
[random] => 2
)
[0] => Array
(
[unix] => 1556547761
[random] => 4
)
[3] => Array
(
[unix] => 1556547765
[random] => 9
)
[2] => Array
(
[unix] => 1556547769
[random] => 5
)
)
You can keep the array key [1],[0],[3],[2]) as it is Or you can keep it as sequential as per your requirement.

PHP - Why doesn't array_multisort function sort correctly?

please view the following code with 2 arrays. i use multisort function with sort flags for ascending and numeric then display. as you can see in the output that array 2 starts with 100 when it should be last. please explain what is causing this and how to sort it correctly. thank you.
<?php
$array1 = array(1,7,10,6);
$array2 = array(100,20,25,10);
array_multisort($array1, SORT_ASC, SORT_NUMERIC, $array2);
print_r($array1);
echo "<br>";
print_r($array2);
?>
output:
Array ( [0] => 1 [1] => 6 [2] => 7 [3] => 10 )
Array ( [0] => 100 [1] => 10 [2] => 20 [3] => 25 )
Ah, yes, array_multisort is a bit tricky to understand the first time round.
Basically the sort is lexicographical, a fancy word meaning that the first array is sorted and the second arrays elements are ordered according to the first array.
Look at your first (output) array and see the order and map it to the initial second array and you'll see whats happening.
So the second array you take the 1st, 4th , 2nd and 3rd elements.
If you just want plain sorting for multiple arrays then just do them one by one or over a loop.

Fastest way of sorting multidimensional arrays in php

Array
(
[0] => Array
(
[t] => 81881
[b] => 99494
)
[1] => Array
(
)
...
...
)
I have a multidimensional array like above.The entries in this array would be ranging upto 20k. I want to sort this array acc. to "t" index without calling any external function. Any suggestions for improving the efficiency.
I doubt there is something faster than array_multisort() http://us2.php.net/array_multisort
UPDATE:
Finding out now, that data is not really multidimensional (it's just a key that's hidden as a val of item in array). It would be probably easier to use something like:
http://php.net/manual/en/function.usort.php
function cmp($a, $b)
{
return $a['t']<=>$b['t'];
}
usort($arr, 'cmp');

sorting array after array_count_values

I have an array of products
$products = array_count_values($products);
now I have an array where $key is product number and $value is how many
times I have such a product in the array.
I want to sort this new array that product with the least "duplicates" are
on the first place, but what ever I use (rsort, krsort,..) i loose product
numbers (key).
any suggestions?
thanks.
Take a look at arsort() as an alternative to rsort() (and that family of functions).
Generally, the 'Sorting arrays' page on php.net might be useful to you - it's a comparison of PHP's array sorting functions based on what they sort, what direction they sort in, and whether they maintain the keys while sorting.
Mind you, for the sake of completion:
Going by 'now I have an array where $key is product number and $value is how many times I have such a product in the array. I want to sort this new array that product with the least "duplicates" are on the first place', you probably want asort() (the pendant to sort()).
Your comment example, using asort():
$arr = array(
1 => 3,
2 => 2,
5 => 3,
9 => 1
);
asort($arr);
print_r($arr);
yields:
Array
(
[9] => 1
[2] => 2
[1] => 3
[5] => 3
)
You want to use asort():
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.
rsort() was wrong from the first place anyway (and so are any other sorting functions that have the r (for reverse) in it), as it would sort the array from highest to lowest.
asort() sorts from lowest to highest:
<?php
$array = array('f'=>1, 'a'=>2, 'c'=>5);
asort($array);
print_r($array);
gives
Array
(
[f] => 1
[a] => 2
[c] => 5
)
Note: These functions sort the arrays in-place. They do not return a sorted array. The return values is:
(..) TRUE on success or FALSE on failure.
Try using asort() or arsort() or any other sort function that maintains index association.
You should use asort() PHP function.
asort() is array sort, not ascending sort.
dsort doesn't exist. The function you are looking for is arsort() - array reverse sort.
https://www.php.net/manual/en/function.asort.php
https://www.php.net/manual/en/function.arsort.php
Just a thought;
asort - sorts ascending (low to high)
perhaps try
dsort - descending (high to low)

PHP's USORT Callback Function Parameters

This is a really esoteric question, but I'm genuinely curious. I'm using usort for the first time today in years, and I'm particularly interested in what exactly is going on. Suppose I've got the following array:
$myArray = array(1, 9, 18, 12, 56);
I could sort this with usort:
usort($myArray, function($a, $b){
if ($a == $b) return 0;
return ($a < $b) ? -1 : 1;
});
I'm not 100% clear about what is going on with the two parameters $a and $b. What are they, and what do they represent. I mean, I could assume that $a represents the current item in the array, but what exactly is this getting compared to? What is $b?
I could increase my array to include strings:
$myArray = array(
array("Apples", 10),
array("Oranges", 12),
array("Strawberries", 3)
);
And run the following:
usort($myArray, function($a, $b){
return strcmp($a[0], $b[0]);
});
And that would sort my child-arrays alphabetically based upon the [0] index value. But this doesn't offer any clarity about what $a and $b are. I only know that the match the pattern that I'm seeking.
Can somebody offer some clarity about what is actually taking place?
The exact definition of $a and $b will depend upon the algorithm used to sort the array. To sort anything you have to have a means to compare two elements, that's what the callback function is used for. Some sorting algorithms can start anywhere in the array, others can start only in a specific part of it so there's no fixed meaning in $a and $b other than they are two elements in the array that have to be compared according to the current algorithm.
This method can be used to shed light upon which algorithm PHP is using.
<?php
$myArray = array(1, 19, 18, 12, 56);
function compare($a, $b) {
echo "Comparing $a to $b\n";
if ($a == $b) return 0;
return ($a < $b) ? -1 : 1;
}
usort($myArray,"compare");
print_r($myArray);
?>
Output
vinko#mithril:~$ php sort.php
Comparing 18 to 19
Comparing 56 to 18
Comparing 12 to 18
Comparing 1 to 18
Comparing 12 to 1
Comparing 56 to 19
Array
(
[0] => 1
[1] => 12
[2] => 18
[3] => 19
[4] => 56
)
From the output and looking at the source we can see the sort used is indeed a quicksort implementation, check for Zend/zend_qsort.c in the PHP source (the linked to version is a bit old, but hasn't changed much).
It picks the pivot in the middle of the array, in this case 18, then it needs to reorder the list so that all elements which are less (according to the comparison function in use) than the pivot come before the pivot and so that all elements greater than the pivot come after it, we can see it doing that when it compares everything to 18 at first.
Some further diagrammatic explanation.
Step 0: (1,19,18,12,56); //Pivot: 18,
Step 1: (1,12,18,19,56); //After the first reordering
Step 2a: (1,12); //Recursively do the same with the lesser, here
//pivot's 12, and that's what it compares next if
//you check the output.
Step 2b: (19,56); //and do the same with the greater
To sort anything you need a means to compare two items and figure out if one comes before the other. This is what you supply to usort. This function will be passed two items from your input array, and returns the order they should be in.
Once you have a means to compare two elements, you can use sort-algorithm-of-your-choice.
If you are unfamiliar, you might like to look at how a simple naive algorithm like bubblesort would use a comparison function.
Behind the scenes, PHP is using a quicksort.
usort() or uasort() have a human-feeling bug on sorted result. See the code segment:
function xxx($a,$b) { if ($a==$b) return 0; else return $a<$b?-1:1; }
$x=array(1=>10,2=>9,3=>9,4=>9,5=>6,6=>38);
uasort($x,'xxx');
print_r($x);
the result is:
Array ( [5] => 6 [4] => 9 [3] => 9 [2] => 9 [1] => 10 [6] => 38 )
Do you see the bug? No? Ok, let me explain it.
The original three '9' elments are in key order: 2,3,4. But in the result, the three '9' elements are now in key order: 4,3,2, i.e. equal-value elements are in reverse key order after sorting.
If the element is only single value, as in above example,it's fine with us. However, if the element is compound value, then it could cause human-feeling bug. See another code segments. We are to sort many points horizontally, i.e. sort them based on ascending x-coordinate value order :
function xxx($a,$b) { if ($a['x']==$b['x']) return 0; else return $a['x']<$b['x']?-1:1; }
$x=array(1=>array('x'=>1, 'v'=>'l'),2=>array('x'=>9, 'v'=>'love'),
3=>array('x'=>9, 'v'=>'Lara'),4=>array('x'=>9, 'v'=>'Croft'),
5=>array('x'=>15, 'v'=>'and'),6=>array('x'=>38, 'v'=>'Tombraider'));
uasort($x,'xxx');
print_r($x);
the result is:
Array ( [1] => Array ( [x] => 1 [v] => l ) [4] => Array ( [x] => 9 [v] => croft )
[3] => Array ( [x] => 9 [v] => Lara ) [2] => Array ( [x] => 9 [v] => love )
[5] => Array ( [x] => 15 [v] => and ) [6] => Array ( [x] => 38 [v] => Tombraider ) )
You see 'I love Lara Croft and Tombraider' becomes 'I Croft Lara love and Tombraider'.
I call it human-feeling bug because it depends on what case you use and how you feel it should be sorted in real world when the compared values are same.

Categories