How to arrange multiple arrays by a specific field - php

I have an array that has multiple arrays inside it. I am trying to arrange those arrays from the amount of greatest to least new_sales. Here is the example of the array which goes on for about 40 arrays:
Array
(
[0] => Array
(
[Tech] => Array
(
[first_name] => Anthony
[last_name] => Bisignano
)
[0] => Array
(
[new_sales] => 21
[upgrades] => 2
)
)
[1] => Array
(
[Tech] => Array
(
[first_name] => Arnold
[last_name] => Ybanez
)
[0] => Array
(
[new_sales] => 5
[upgrades] => 0
)
)
The function I am trying to use is the following:
function aasort (&$techs, $key) {
$sorter=array();
$ret=array();
reset($techs);
foreach ($techs as $ii => $va) {
$sorter[$ii]=$va[$key];
}
asort($sorter);
foreach ($sorter as $ii => $va) {
$ret[$ii]=$techs[$ii];
}
$techs=$ret;
}
aasort($test,"new_sales");
AM I using this function wrong or is there another approach I should be taking?

There are sorting functions in PHP that support user-defined comparison methods. Code like this should help you get started with that.
function cmp($a, $b)
{
if ($a[0]['new_sales'] == $b[0]['new_sales']) {
return 0;
}
return ($a[0]['new_sales'] < $b[0]['new_sales']);
}
usort($data, "cmp");

In this case you probably want to use usort() such that you can define your sorting logic.
So something like this:
usort($array, function($a, $b) {
if ($a[0]['new_sales'] > $b[0]['new_sales']) {
return -1; // note we use -1 here because we want a reverse sort
} else if ($a[0]['new_sales'] < $b[0]['new_sales']) {
return 1;
} else {
return 0;
}
});

Related

php sorting an array based on value

I have a very big array. Arrays within arrays. Below is a small portion of it;
[lta/] => Array
(
[2012-12-31/] => Array
(
[0] => 31_december_2012.pdf
[1] => 31_december_2012.xls
[2] => key_points.html
)
)
What I need to do, is get the "key_points.html" value to always start at the top of it's array. Example;
[2012-12-31/] => Array
(
[2] => key_points.html
[0] => 31_december_2012.pdf
[1] => 31_december_2012.xls
)
)
I cannot do a simple asort because I never know at which point "key_points.html" is going to appear in the array.
I tried to rename the values "key_points.html" with a view to sorting it and then un-renaming it after;
foreach($the_array as $array_object => $array_item)
{
if($array_item == "key_points.html") {$array_item = "0001_key_points.html";}
}
But that literally seemed to have no effect! it didn't even rename my value. I also tried the same thing with string replace;
$the_array = str_replace("key_points.html", "0001_key_points.html", $the_array);
Is there a function perhaps that allows you to specify a string, and move that to the top of each array each time if it finds it??
Use uasort to specify a custom comparator callback:
uasort($array, function($a, $b) {
if($a == 'key_points.html') return -1; // Smaller than all
if($b == 'key_points.html') return 1; // Larger than all
return ($a < $b) ? -1 : 1; // Default sorting
});
Syntax is assuming an up to date PHP (5.3+) with support for anonymous functions.
Use custom function
function customSort (&$array, $key) {
$sorter=array();
$ret=array();
reset($array);
foreach ($array as $ii => $val) {
$sorter[$ii]=$va[$key];
}
asort($sorter);
foreach ($sorter as $ii => $val) {
$ret[$ii]=$array[$ii];
}
$array=$ret;
}
customSort($your_array,"2");

Sort array by key value

So I have this array.
Array
(
[0] => Array
(
[key_1] => something
[type] => first_type
)
[1] => Array
(
[key_1] => something_else
[type] => first_type
)
[2] => Array
(
[key_1] => something_else_3
[type] => second_type
)
[3] => Array
(
[key_1] => something_else_4
[type] => second_type
)
)
I have to sort by type value in a pattern like this:
first_type
second_type
first_type
second_type
My questions is, how can I do this?
Thanks a lot!
You need to use usort with a custom comparison function that compares the key_1 sub-keys of each item (you can use strcmp to do this conveniently). Assuming you do not want to change the structure of the resulting array, it would look something like this:
$arr = /* your array */
usort($arr, function($a, $b) { return strcmp($a['key_1'], $b['key_1']); });
So here's how I got it to work:
function filter_by_value($array, $index, $value) {
if(is_array($array) && count($array) > 0) {
foreach(array_keys($array) as $key){
$temp[$key] = $array[$key][$index];
if ($temp[$key] == $value){
$newarray[$key] = $array[$key];
}
}
}
return $newarray;
}
$array = /* array here */
$type1 = array_values(filter_by_value($array, 'type', '1'));
$type2 = array_values(filter_by_value($array, 'type', '2'));
$i = 1; $x = 1; $y = 1;
$sorted = array();
foreach ($array as $a) {
if ($i % 2) {
$sorted[$i-1] = $type1[$x-1];
$x++;
} else {
$sorted[$i-1] = $type2[$y-1];
$y++;
}
$i++;
}
Found filter_by_value() on php.net but I don't remember where so, that's not made by me.
Maybe this is not the best solution but it works pretty fine.
If sort() and its relevant alternatives don't work you will have to use usort() or uasort() with a custom function to sort this array.

Question about PHP usort function

i've got a PHP script where i rearange a multidimensional array with the use of the usort()-function.
this is a sample array (print_r-output) of array $arr
Array
(
[3] => Array
(
[name] => Bjudningen
[grade] => 5
[grade_type] => calculated
[orgname] => LInvitation
[id] => 13975
)
[0] => Array
(
[name] => Coeur fidèle
[grade] => 3
[grade_type] => calculated
[orgname] => Coeur fidèle
[id] => 8075
)
[2] => Array
(
[name] => Dawsonpatrullen
[grade] => 5
[grade_type] => calculated
[orgname] => The Dawson Patrol
[id] => 13083
)
)
And this is my PHP script
function sort_movies($arr,$val){
function cmp($x, $y)
{
if ( $x[$val] == $y[$val] )
return 0;
else if ( $x[$val] < $y[$val] )
return -1;
else
return 1;
}
usort($arr, 'cmp');
return $arr;
}
$sorted = sort_movies($arr,"grade");
I want to be able to sort the array on different subkeys (i.e. name, grade,id), but it doesn't work the way i do it above. however if i change $val in the sort movies function to the value "grade" it does work, so for some reason it won't allow me to send in a vaiable as the sort parameter.
what is it i'm doing wrong?
May be try this by send index of subkey i.e. grade instead of name of subkey .
With 5.3 you can do it like this:
function create_sort($key)
{
return function($x,$y) use($key)
{
return $x[$key] - $y[$key];
};
}
$sorter = create_sort('name');
usort($arr, $sorter);
The problem is that $val is only available within the scope of the function sort_movies(), not in the scope of cmp(). You need to just declare it as global. This will pull it into scope so you can use it within the cmp() function.
function sort_movies($arr,$val){
function cmp($x, $y)
{
global $val; // <---------------------------------
if ( $x[$val] == $y[$val] )
return 0;
else if ( $x[$val] < $y[$val] )
return -1;
else
return 1;
}
usort($arr, 'cmp');
return $arr;
}
$sorted = sort_movies($arr,"grade");
http://php.net/manual/en/language.variables.scope.php

Sorting array according to the values in PHP

I have the following array
[0] => Array
(
[id] => 229
[val] => 2
)
[3] => Array
(
[id] => 237
[val] => 1
)
[4] => Array
(
[id] => 238
[val] => 6
)
I need to sort this array according to the val values in the array, and do not know how to accomplish this?
function cmp($a, $b)
{
if ($a["val"] == $b["val"]) {
return 0;
}
return ($a["val"] < $b["val"]) ? -1 : 1;
}
usort($yourarray, "cmp");
Read this for more information.
array_multisort can help with this, example 3 presents a similar problem and solution.
This would help - http://www.informit.com/articles/article.aspx?p=341245&seqNum=7
You can use array_multisort()
Examples here: http://www.php.net/manual/en/function.array-multisort.php
The Example #3 Sorting database results is what you want. Might be easier if you are not familiar with callback functions and usort().
use this function to sort array accroding to your need
function sksort(&$array, $subkey="id",$sort_ascending=false)
{
if (count($array))
$temp_array[key($array)] = array_shift($array);
foreach($array as $key => $val){
$offset = 0;
$found = false;
foreach($temp_array as $tmp_key => $tmp_val)
{
if(!$found and strtolower($val[$subkey]) > strtolower($tmp_val[$subkey]))
{
$temp_array = array_merge(
(array)array_slice($temp_array,0,$offset),
array($key => $val),
array_slice($temp_array,$offset)
);
$found = true;
}
$offset++;
}
if(!$found) $temp_array = array_merge($temp_array, array($key => $val));
}
if ($sort_ascending) $array = array_reverse($temp_array);
else $array = $temp_array;
}
==========================================================================
now use this function in ur array
sksort($arrayname, "val"); /* for ascending */
sksort($arrayname, "val", true); /* for descending */

Sorting an associative array in PHP [duplicate]

This question already has answers here:
How can I sort arrays and data in PHP?
(14 answers)
Closed 8 years ago.
I have an array in this format:
Array
(
[0] => Array
(
[text] => tests
[language] =>
[advertiserCompetitionScale] => 5
[avgSearchVolume] => 7480000
[lastMonthSearchVolume] => 9140000
)
[1] => Array
(
[text] => personality tests
[language] =>
[advertiserCompetitionScale] => 5
[avgSearchVolume] => 165000
[lastMonthSearchVolume] => 201000
)
[2] => Array
(
[text] => online tests
[language] =>
[advertiserCompetitionScale] => 5
[avgSearchVolume] => 246000
[lastMonthSearchVolume] => 301000
)
)
How can I sort an array in that format, in the descending order of the avgSearchVolume field? Is there a built in function for this?
Use usort and supply your own function to do the ordering, e.g.
function cmp($a, $b)
{
return $b['avgSearchVolume'] - $a['avgSearchVolume'];
}
usort($array, "cmp");
Until PHP 5.3 this is the best function for sorting based on subkeys without making a new function for each key.
function sortBySubkey(&$array, $subkey, $sortType = SORT_ASC) {
foreach ($array as $subarray) {
$keys[] = $subarray[$subkey];
}
array_multisort($keys, $sortType, $array);
}
sortBySubkey($arr, 'avgSearchVolume');
With PHP 5.3 you can make something like this, same function call as now.
function getSortVariable($sortType = SORT_ASC) {
switch($sortType) {
case SORT_ASC:
return function ($a, $b) use ($subkey) { return strcmp($a[$subkey], $b[$subkey]); };
}
}
function sortBySubkey(&$array, $subkey, $sortType = SORT_ASC) {
$sortFunction = getSortVariable($sortType);
usort($array, $sortFunction($subkey));
}
You'll have to use a custom callback function together with usort().
function cmp($a, $b)
{
if ($a['avgSearchVolume'] == $b['avgSearchVolume']) {
return 0;
}
return ($a['avgSearchVolume'] > $b['avgSearchVolume']) ? -1 : 1;
}
usort($array, 'cmp');
function querySort ($first_Array,$second_Array) {
return strcasecmp($first_Array['name'],$second_Array['name']);
}
echo '<pre>';
usort($main, 'querySort');
print_r($main);
die;
Here is another solution, You can add multiple options for sorting(See the commented section of the code)
<?php
$arr=Array(
Array("text" => "tests","language" =>"","advertiserCompetitionScale" => 5,"avgSearchVolume" => 7480000,"lastMonthSearchVolume" => 9140000),
Array("text" => "personality tests","language" =>"","advertiserCompetitionScale" => 5,"avgSearchVolume" => 165000,"lastMonthSearchVolume"=>201000),
Array("text" => "online tests","language" =>"","advertiserCompetitionScale" => 5,"avgSearchVolume" => 246000,"lastMonthSearchVolume" =>301000)
);
$sort = array();
foreach($arr as $k=>$v) {
$sort['avgSearchVolume'][$k] = $v['avgSearchVolume'];
//$sort['text'][$k] = $v['text'];
}
array_multisort($sort['avgSearchVolume'], SORT_DESC, $arr);
//array_multisort($sort['avgSearchVolume'], SORT_DESC, $sort['text'], SORT_ASC,$arr);
echo "<pre>";
print_r($arr);
?>
REF: http://php.net/manual/en/function.array-multisort.php

Categories