Sorting from high to low in array - php

Array (
[0] => Array (
[2] => 9.6
)
[1] => Array (
[497] => 11.666666666667
)
[2] => Array (
[451] => 34
)
[3] => Array (
[459] => 8.8
)
[4] => Array (
[461] => 22.5
)
)
I have this array.
How can I sort it by number value?
I tried
usort($array, function ($a, $b)
{
return $a[0] < $b[0];
});
But doesn't work.

First things first... from the manual
value_compare_func
The comparison function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.
Emphasis on the "integer" part.
From PHP 7, you can use the spaceship operator for this.
You need to do some extra work though to address your non-sequential array keys. You can get the first value using reset()
usort($array, function($a, $b) {
return reset($b) <=> reset($a);
});
Demo ~ https://3v4l.org/uni3v (doesn't work in PHP 5.x)
The pre PHP 7 version can be achieved with a simple subtraction. For example
return reset($b) - reset($a);

Try this:
$numbers = [1, 3, 2];
usort($numbers, function ($a, $b) {
return $a < $b ? 1 : ($a === $b ? 0 : -1);
});
print_r($numbers);
Result is:
Array
(
[0] => 3
[1] => 2
[2] => 1
)

Related

PHP:: Double sort an array by priority

My goal is to sort an array first by the string length and after that sort it again by character value without changing the priority of the length.
Here is my code:
$arr=array("an","am","alien","i");
usort($arr, function ($a, $b) { return (strlen($a) <=> strlen($b)); });
print_r($arr);
I am getting :
Array ( [0] => i [1] => an [2] => am [3] => alien )
...almost but not there)
You're missing the logic to account for sorting by character value. You can add that logic into your custom sort method:
// if lengths are the same, then sort by value
if (strlen($a) == strlen($b)) {
return $a <=> $b;
}
// otherwise, sort by length
return (strlen($a) <=> strlen($b));
You can combine this into a single line by using a ternary:
return strlen($a) == strlen($b) ? $a <=> $b : strlen($a) <=> strlen($b);
Full example (https://3v4l.org/msISD):
<?php
$arr=array("aa", "az", "an","am", "ba", "by", "alien","i");
usort($arr, function ($a, $b) {
return strlen($a) == strlen($b) ? $a <=> $b : strlen($a) <=> strlen($b);
});
print_r($arr);
outputs:
Array
(
[0] => i
[1] => aa
[2] => am
[3] => an
[4] => az
[5] => ba
[6] => by
[7] => alien
)

PHP array diff different types

I have 2 arrays of data from different data sources in different formats, but they represent the same resources. So id in one is the same as guid in the other for example.
Currently I am converting one of the arrays to match the other, and then running them via array_udiff to get the difference.
However, I need to compare 3 properties to check if they are a match, so I can't return -1,0,1 as the 3 fields either match, or do not match.
If I simply return -1 or 0, it works comparing $a to $b, but fails comparing $b to $a
$arr_a = [['id'=>1, 'a'=>1, 'b'=>0],['id'=>2, 'a'=>2, 'b'=>3],['id'=>3, 'a'=>1, 'b'=>0]];
$arr_b = [['id'=>3, 'a'=>1, 'b'=>0],['id'=>4, 'a'=>2, 'b'=>3],['id'=>5, 'a'=>1, 'b'=>0]];
function diff($a, $b) {
if( ($a['id'] == $b['id'])
&& ($a['a'] == $b['a'])
&& ($a['b'] == $b['b'])
) {
return 0;
} else {
return -1;
}
$not_in_b = array_udiff($arr_a, $arr_b,'diff');
$not_in_a = array_udiff($arr_b, $arr_a,'diff');
print_r($not_in_b);
print_r($not_in_a);
The above returns...
Array
(
[0] => Array
(
[id] => 1
[a] => 1
[b] => 0
)
[1] => Array
(
[id] => 2
[a] => 2
[b] => 3
)
)
Array
(
[0] => Array
(
[id] => 3
[a] => 1
[b] => 0
)
[1] => Array
(
[id] => 4
[a] => 2
[b] => 3
)
[2] => Array
(
[id] => 5
[a] => 1
[b] => 0
)
)
As you can see the diff of $a to $b works, but $b to $a does not...
How can I compare multiple vaules like this for equality...
UPDATE
This works, but making two arrays with the three identifying properties values as the keys...
$arr_a = [['id'=>1, 'a'=>1, 'b'=>0],['id'=>2, 'a'=>2, 'b'=>3],['id'=>3, 'a'=>1, 'b'=>0]];
$arr_b = [['id'=>3, 'a'=>1, 'b'=>0],['id'=>4, 'a'=>2, 'b'=>3],['id'=>5, 'a'=>1, 'b'=>0]];
$arra_a_keys=[];
foreach($arr_a as $item) {
$arra_a_keys[$item['id'].'_'.$item['a'].'_'.$item['b']] = $item;
}
$arra_b_keys=[];
foreach($arr_b as $item) {
$arra_b_keys[$item['id'].'_'.$item['a'].'_'.$item['b']] = $item;
}
$not_in_b = array_diff_key($arra_a_keys, $arra_b_keys);
$not_in_a = array_diff_key($arra_b_keys, $arra_a_keys);
print_r($not_in_b);
print_r($not_in_a);
To compare by ids only you can do the following:
$ids = array_column($a, 'id');
$guids = array_column($b, 'guid');
$not_in_b = array_filter($a, function ($item) use ($guids) {
return !in_array($item['id'], $guids);
});
$not_in_a = array_filter($b, function ($item) use ($ids) {
return !in_array($item['guid'], $ids);
});
Here is working demo.
Addition:
Also, you can do it with array_udiff:
$compareFunction = function ($a, $b) {
$id1 = isset($a['id']) ? $a['id'] : $a['guid'];
$id2 = isset($b['id']) ? $b['id'] : $b['guid'];
return strcmp($id1, $id2);
};
$not_in_b = array_udiff($a, $b, $compareFunction);
$not_in_a = array_udiff($b, $a, $compareFunction);
Here is working demo.
But be aware array_udiff is really not the most straight forward function. There is nothing about this in the documentation, but it not only compares but also sorts the arrays you provided with a callback function. That's why
The comparison function must return an integer less than, equal to, or
greater than zero if the first argument is considered to be
respectively less than, equal to, or greater than the second.
But this sorting also tricks the programmer, because he expected to that in function int callback ( mixed $a, mixed $b ) $a comes from $array1 and $b comes from $array2. That is not the case. You can read this article to find out more details. So I think that array_filter solution is more understandable
You could use a foreach for make array comparable
$ids1 = [];
foreach($a as $v1){
$i1[] = $v1['id'];
}
$ids2 = [];
foreach($b as $v2){
$i2[] = $v2['guid'];
}
$one_notin_two = array_diff($i1,$i2);
$two_notin_one = array_diff($i2,$i1);
You can solve this using array_column() and array_diff().
Here is sample code: See Live Demo
$a = [['id' => 1], ['id' => 2], ['id' => 3], ['id' => 4]];
$b = [['guid' => 3], ['guid' => 4], ['guid' => 6], ['guid' => 7]];
$a = array_column($a, 'id');
$b = array_column($b, 'guid');
$not_in_b = array_diff($a, $b);
$not_in_a = array_diff($b, $a);
Hope it should be solved your problem. Thank you.

how to sort two dimentional array in descending array in php? [duplicate]

This question already has answers here:
How can I sort arrays and data in PHP?
(14 answers)
Closed 6 years ago.
i have the following array and i want to sort this array in descending order on the base of the "count" index value in php. i have used the following code but it is not working for me. please give me hint to sort array in descending order.
Array:-
Array ( [0] => Array ( [text] => this is text [count] => 0 )
[1] => Array ( [text] => this is second text [count] => 2 )
[2] => Array ( [text] => this is third text [count] => 1 )
)
I have tried the following code.
function sort_count($a, $b) {
return $a['count'] - $b['count'];
}
$sorted_array = usort($array, 'sort_count');
Ascending..
usort($your_array, function($a, $b) {
return $a['count'] - $b['count'];
});
Descending..
usort($your_array, function($a, $b) {
return $b['count'] - $a['count'];
});
Example here
Try this:
Note: Checking your equality acts as an added advantage.
function sort_count($a, $b) {
if ($a['count'] === $b['count']) {
return 0;
} else {
return ($a['count'] > $b['count'] ? 1:-1);
}
}
$sorted_array = usort($array, 'sort_count');
echo "<pre>";
print_r($array);
echo "</pre>";
Hope this helps.
you can use core php functions like
rsort ($array)
arsort($array)
also you should read this in php manual
http://php.net/manual/en/array.sorting.php
Here is the solution:
$a1 = array (array ( "text" => "this is text", "count" => 0 ),
array ( "text" => "this is text", "count" => 1 ),
array ( "text" => "this is text", "count" => 2 ),
);
usort($a1 ,sortArray('count'));
function sortArray($keyName) {
return function ($a, $b) use ($keyName) {return ($a[$keyName]< $b[$keyName]) ? 1 : 0;
};
}
print_r($a1);

PHP - Sort arrays by keys and values

Hello how to sort arrays by keys and values too... so if user input this value
$input = array(0,1,0,2,0);
then the result should be like this since they're the same input they should maintain their keys too...
Array
(
[0] => 0
[2] => 0
[4] => 0
[1] => 1
[3] => 2
)
not like this... the keys is jumbled and I really that key to work on my project of FCFS Scheduling.
Array
(
[4] => 0
[0] => 0
[2] => 0
[1] => 1
[3] => 2
)
btw I used asort. someone help me how to fix this?
function cmp($a, $b)
{
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
$a = array(0,1,0,2,0);
usort($a, "cmp");
foreach ($a as $key => $value) {
echo " $value\n";
}
Stable sort would help here. But php don't have any stable sorting functions since 4.1.
But you can use uksort + closure.
$input = array(0,1,0,2,0);
$cmp = function($a, $b) use($input){
if($input[$a] > $input[$b]){return 1;}
elseif($input[$a] < $input[$b]){return -1;}
elseif($a>$b){return 1;}
elseif($a<$b){return -1;}
return 0;
};
uksort($input, $cmp);
print_r($input);
https://eval.in/145923
Or shorter version
$cmp = function($a, $b) use($input){
return (($input[$a]-$input[$b])?:($a-$b));
};
Simple use the sort function
$input = array(0,1,0,2,0);
sort($input);
Result:-
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 1
[4] => 2
)

Sort array by sub array

I have array:
$array = array(array('2012-12-12', 'vvv'), array('2012-12-14', 'df'),array('2012-12-10', 'vvv'),array('2012-12-11', 'vvv'));
Array
(
[0] => Array
(
[0] => 2012-12-12
[1] => vvv
)
[1] => Array
(
[0] => 2012-12-14
[1] => df
)
[2] => Array
(
[0] => 2012-12-10
[1] => vvv
)
[3] => Array
(
[0] => 2012-12-11
[1] => vvv
)
)
http://codepad.org/gxw2yKMU
is possible to sort this with dates DESC? For this example should be:
$array[1] //2012-12-14
$array[0] //2012-12-12
$array[3] //2012-12-11
$array[2] //2012-12-10
For me the best way is use embedded functions for PHP, but how? :)
You can use usort with a custom function. If you're on PHP < 5.3 you'll need a named function rather than, as I have, an anonymous one.
$array = array(
array('2012-12-12', 'vvv'),
array('2013-12-14', 'df'),
array('2012-12-14', 'df'),
array('2012-12-10', 'vvv'),
array('2012-12-11', 'vvv')
);
usort($array, function($a, $b) {
if ($a[0] == $b[0]) return 0;
return ($a > $b) ? -1 : 1;
});
print_r($array);
You should be able to use usort
usort( $array, 'sortFunction' );
function sortFunction( $a, $b ) {
if( $a[0] == $b[0] )
return 0;
return ( $a[0] > $b[0] ? return -1 : 1 );
}
You can use array_multisort() :
foreach ($array as $key => $row) {
$dates[$key] = $row[0];
}
array_multisort($dates, SORT_DESC, $array);
First, you put out all dates in a new array. Then, array_multisort() will sort the second array ($array) in the same order than the first ($dates)

Categories