sorting array based on inner-array key-value [duplicate] - php

This question already has answers here:
How can I sort arrays and data in PHP?
(14 answers)
Closed 7 years ago.
I have an array like one mentioned below
Array
(
[6] => Array
(
[name] => Extras
[total_products] => 0
[total_sales] => 0
[total_affiliation] => 0
)
[5] => Array
(
[name] => Office Products
[total_products] => 7
[total_sales] => 17
[total_affiliation] => 8
)
[1] => Array
(
[name] => Hardware Parts
[total_products] => 6
[total_sales] => 0
[total_affiliation] => 0
)
)
Right now, order is: Extras, Office Products, Hardware Parts
I want to sort main array in such as way that it is order by total_sales of inner-array in desc order
so order will be: Office Products, Extras, Hardware Parts
Any help guys

PHP 5.3:
usort($array, function ($a, $b) { return $b['total_sales'] - $a['total_sales']; });
PHP 5.2-:
usort($array, create_function('$a,$b', 'return $b["total_sales"] - $a["total_sales"];'));

Use a custom function and usort:
<?php
function custom_sale_sort($a, $b)
{
if ($a['total_sales'] < $b['total_sales'])
return 1;
elseif ($a['total_sales'] == $b['total_sales'])
return 0;
else
return -1;
}
usort($array, 'custom_sale_sort');
If you need your array sorted in the other direction, then switch the (1,-1) values around in the custom function.

Here is the class you can use to do multidimension sort
Note: You must have PHP5
class MultiDimensionSort
{
const ASCENDING = 0,DESCENDING = 1;
public $sortColumn,$sortType;
public function __construct($column = 'price', $type = self::ASCENDING)
{
$this->column = $column;
$this->type = $type;
}
public function cmp($a, $b)
{
switch($this->type)
{
case self::ASCENDING:
return ($a[$this->column] == $b[$this->column]) ? 0 : (($a[$this->column] < $b[$this->column]) ? -1 : 1);
case self::DESCENDING:
return ($a[$this->column] == $b[$this->column]) ? 0 :(($a[$this->column] < $b[$this->column]) ? 1 : -1);
default:
assert(0); // unkown type
}
}
}
Like you have array named summary with contain above array. than you can do sort by following statements.
// assuming your array variable is $summary
$s = new MultiDimensionSort('total_sales', MultiDimensionSort::DESCENDING); // sort by total_sales
usort($summary, array($s, 'cmp'));
print"<pre>";print_r($summary);
Cheers!
May be this ll help you

Related

sort an Array of dates from the smallest date on php [duplicate]

This question already has answers here:
How to sort date array in php?
(8 answers)
Closed 1 year ago.
I need to sort an array from the smallest date. I used Usort, but it order the array considering just the day. I tried using a code from an example using sort in javascript but i need this happen in php or find a way to convert php array to js.
Here is the code:
<?php
ArrayDates ( [0] => 22/03/2018 [1] => 09/04/2018 [2] => 26/03/2018
[3] => 27/11/2017 [4] => 22/01/2018 [5] => 06/09/2017 )
?>
<script>
ArrayDates.sort(function (a, b){
var aa = a.split('-'),
bb = b.split('-');
return aa[2] - bb[2] || aa[1] - bb[1] || aa[0] - bb[0];
})
</script>
Hi finally i found a solution in a forum and maybe can help to someone else. The solution is create a new array of timestamps based on the original array. Then sort this new array. After just echo the first element of the new array with "date" and will return the first date. Here is the code:
<?php
$ArrayDates= array ('22/03/2018','09/04/2018', '26/03/2018',
'27/11/2017','22/01/2018', '06/09/2017');
function date_to_timestamp($d){
$newarr = array();
foreach($d as $f) {
$arr=explode("/",$f);
array_push($newarr, mktime(0,0,0,$arr[0],$arr[1],$arr[2]));
}
return $newarr;
}
function cmp2($a, $b)
{
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
$third = date_to_timestamp($ArrayDates);
usort($third, "cmp2");
echo date('m/d/Y', $third[0]);
?>
This will sort the array of date in ascending order.
$date = array('23-02-2012','21-01-2014','11-01-2010','09-02-2001','01-01-2019');
function date_sort($a, $b) {
return strtotime($a) - strtotime($b);
}
usort($date, "date_sort");
print_r($date);
Output:-
Array (
[0] => 09-02-2001
[1] => 11-01-2010
[2] => 23-02-2012
[3] => 21-01-2014
[4] => 01-01-2019
)

Sorting of multidimensional array with with numbers and letters

How to sort multidimensional array. This is what my array looks like
[0] => Array
(
[id] => 1
[title] => 3A
[active] => 1
)
[1] => Array
(
[id] => 1
[title] => A
[active] => 1
)
[2] => Array
(
[id] => 1
[title] => 2A
[active] => 1
)
[3] => Array
(
[id] => 1
[title] => B
[active] => 1
)
I have tried several usort methods, but cannot seem to get this to work. I am needing the array sorted so that it will sort by numeric then by alpha numeric like so: A,B,2A,3A.
I am not sure if this would be possible without adding a position field to dictate what order the titles are suppose to be in, or am I missing something here?
You can build a "key" for each item where the digit part is padded on the left with 0s, this way, the sort function can perform a simple string comparison:
$temp = [];
foreach ($arr as $v) {
$key = sscanf($v['title'], '%d%s');
if (empty($key[0])) $key = [ 0, $v['title'] ];
$key = vsprintf("%06d%s", $key);
$temp[$key] = $v;
}
ksort($temp);
$result = array_values($temp);
demo
This technique is called a "Schwartzian Transform".
As #Kargfen said, you can use usort with your custom function. Like this one :
usort($array, function(array $itemA, array $itemB) {
return myCustomCmp($itemA['title'], $itemB['title']);
});
function myCustomCmp($titleA, $titleB) {
$firstLetterA = substr($titleA, 0, 1);
$firstLetterB = substr($titleB, 0, 1);
//Compare letter with letter or number with number -> use classic sort
if((is_numeric($firstLetterA) && is_numeric($firstLetterB)) ||
(!is_numeric($firstLetterA) && !is_numeric($firstLetterB)) ||
($firstLetterA === $firstLetterB)
) {
return strcmp($firstLetterA, $firstLetterB);
}
//Letters first, numbers after
if(! is_numeric($firstLetterA)) {
return -1;
}
return 1;
}
This compare-function is just based on the first letter of your titles, but it can do the job ;-)
You can resolve that problem with help of usort and custom callback:
function customSort($a, $b)
{
if ($a['id'] == $b['id']) {
//if there is no number at the beginning of the title, I add '1' to temporary variable
$aTitle = is_numeric($a['title'][0]) ? $a['title'] : ('1' . $a['title']);
$bTitle = is_numeric($b['title'][0]) ? $b['title'] : ('1' . $b['title']);
if ($aTitle != $bTitle) {
return ($aTitle < $bTitle) ? -1 : 1;
}
return 0;
}
return ($a['id'] < $b['id']) ? -1 : 1;
}
usort($array, "customSort");
At first the function compares 'id' values and then if both items are equal it checks 'title' values.

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);

Stable sort with multiple conditions

Hi i am facing problem in sorting multidimensional array by different key,such as by date, by category, by weight in any specific order.
I can not order these array by mysql order by feature as i have to implement a tough business logic on mysql output array (data)..
After implementing business logic i found following type of array that need to be sorted by
date asc,category desc,weight asc.
array have size of 10000 or more.
i have already used usort function but it can't resolve issue of fixed ordering in case of same value of sorting elements.
plz help.
Array
(
[0] => Array
(
[categorie] => xyz
[date] => 2012-12-08 19:30
[weight] => 3
[row_id] => 125812
[searchtype] => show
[uitgespeeld] => 0
)
[1] => Array
(
[categorie] => show
[date] => 2012-12-10 20:15
[weight] => 3
[row_id] => 125816
[searchtype] => show
[uitgespeeld] => 0
)
[2] => Array
(
[categorie] => abc
[date] => 2012-12-13 20:30
[weight] => 3
[row_id] => 119151
[searchtype] => show
[uitgespeeld] => 0
)
.......
)
Code i have used for sorting.
usort($temp_group_data, array('className','cmp_weight'));
usort($temp_group_data, array('className','cmp_date'));
function cmp_weight($a, $b) {
if (($a['weight']==$b['weight']) ) {
return 0;
} else if ($a['weight'] >$b['weight']) {
return -1;
} else {
return 1;
}
}
function cmp_date($a, $b) {
if (($a['date']==$b['date']) ) {
return 0;
} else if (strtotime($a['date']) >strtotime($b['date'])) {
return -1;
} else {
return 1;
}
}
You have to do it in one function, now second sorting overwrites changes made in first.
function multicompare($a,$b){
$criteria = array(
'date' => 'asc',
'category' => 'desc',
'weight' => 'asc'
);
foreach($criteria as $what => $order){
if($a[$what] == $b[$what]){
continue;
}
return (($order == 'desc')?-1:1) * strcmp($a[$what], $b[$what]);
}
return 0;
}
The problem is two-fold, judging by the last part of your question:
All conditions must be evaluated at the same time rather than consecutively.
You need stable sorting to retain the ordering in case two values are the same (i.e. the original order)
Both steps in one goes like this; first you "decorate" the array using the index in which they appear in the original array:
foreach ($a as $key => &$item) {
$item = array($item, $key); // add array index as secondary sort key
}
usort($a, 'mysort'); // sort it
// undecorate
foreach ($a as $key => &$item) {
$item = $item[0]; // remove decoration from previous step
}
And here's the all-in-one sorting function:
function mysort($a, $b)
{
if ($a[0]['date'] != $b[0]['date']) {
return $a[0]['date'] < $b[0]['date'] ? -1 : 1; // ASC
} elseif ($a[0]['category'] != $b[0]['category']) {
return $a[0]['category'] < $b[0]['category'] ? 1 : -1; // DESC
} elseif ($a[0]['weight'] != $b[0]['weight']) {
return $a[0]['weight'] < $b[0]['weight'] ? -1 : 1; // ASC
} else {
return $a[1] < $b[1] ? -1 : 1; // ASC
}
}

PHP Array sorting using child nodes?

Ok I have the following array:
Array
(
[0] => Array
(
[id] => 6
[name] => This Course
[time] => 1288082700
[description] => blah blah .
[link] => http://this.com/?g=5
[course] => 22
)
[1] => Array
(
[id] => 2
[name] => Workshop
[time] => 1287561600
[description] => This description
[link] => http://this.com/?g=5
[session] => 8
[course] => 23
[type] => standard
[adobelink] =>
)
)
How can I sort this entire array by using the inner 'time' key ?
Thanks!
You can use the usort function as:
function cmp($a,$b) {
return $a['time'] - $b['time'];
}
usort($arr,'cmp');
Working link
Use usort():
This function will sort an array by its values using a user-supplied comparison function. If the array you wish to sort needs to be sorted by some non-trivial criteria, you should use this function.
Example:
function cmp($a, $b) {
if ($a['time'] == $b['time']) {
return 0;
}
return ($a['time'] < $b['time']) ? -1 : 1;
}
usort($array, 'cmp');
Of course this will fail if an array has no time element. What should happen then depends on your requirements so I will leave the error handling to you ;)
Use PHP usort() function: http://php.net/manual/en/function.usort.php
First, define a function that will decide on compare result for your data structure:
function cmp($a, $b)
{
if ($a['time'] == $b['time']) {
return 0;
}
return ($a['time'] < $b['time']) ? -1 : 1;
}
Then call usort() and give the nmae of your function to it:
usort($array, "cmp");
You're done!
uasort() will maintain your keys1.
uasort($a, function($a, $b) {
$a = $a['time']; // Assuming keys exist
$b = $b['time'];
if ($a == $b) {
return 0;
} else {
return $a < $b ? -1 : 1; // Reverse < if sort order is wrong
}
});
Anonymous function syntax requires PHP 5.3+! Pass the name of the comparison function if <5.3 (see other answers).
1) In case you care about the keys, too. If not, just use the usort() approach found in abundance above :) The comparison function are basically identical (except for #codaddict's elegant approach).
http://dk.php.net/usort
function sortByTime($a, $b)
{
if ($a['time'] > $b['time'])
{
return 1;
}
else if ($a['time'] < $b['time'])
{
return -1;
}
return 0;
}
usort($yourArray, 'sortByTime');

Categories