Sort multidimensional Array with an index - php

I have the following array and I want to sort all the records with total in descending order. Can anyone tell me the php code or pseudo code for doing it.
Array
(
[reg_id] => Array
(
[0] => 5
[1] => 7
[2] => 17
[3] => 18
[4] => 19
[5] => 20
[6] => 34
)
[name] => Array
(
[0] => employee1
[1] => employee6
[2] => employee3
[3] => employee4
[4] => employee2
[5] => empoyee5
[6] => employee9
)
[test_w] => Array
(
[0] => 21/30
[1] => 15/30
[2] => 27/30
[3] => 16.5/30
[4] => 21/30
[5] => 18/30
[6] => 12/30
)
[intr_w] => Array
(
[0] => 8/10
[1] => 6/10
[2] => 9/10
[3] => 9/10
[4] => 3.3/10
[5] => 7/10
[6] => 0/10
)
[exp_w] => Array
(
[0] => 2.5/5
[1] => 4/5
[2] => 4.35/5
[3] => 4.5/5
[4] => 4.8/5
[5] => 4.5/5
[6] => 0/5
)
[educ_w] => Array
(
[0] => 37.41/55
[1] => 44.14/55
[2] => 33.27/55
[3] => 38.43/55
[4] => 34.52/55
[5] => 46.11/55
[6] => 43.66/55
)
[total] => Array
(
[0] => 68.91
[1] => 69.14
[2] => 73.62
[3] => 68.43
[4] => 63.62
[5] => 75.61
[6] => 55.66
)
)

Use this function should solve the problem
function multisort($array, $key, $sort_flags = SORT_REGULAR) {
if (is_array($array) && count($array) > 0) {
if (!empty($key)) {
$mapping = array();
foreach ($array as $k => $v) {
$sort_key = '';
if (!is_array($key)) {
$sort_key = $v[$key];
} else {
// #TODO This should be fixed, now it will be sorted as string
foreach ($key as $key_key) {
$sort_key .= $v[$key_key];
}
$sort_flags = SORT_STRING;
}
$mapping[$k] = $sort_key;
}
asort($mapping, $sort_flags);
$sorted = array();
foreach ($mapping as $k => $v) {
$sorted[] = $array[$k];
}
return $sorted;
}
}
return $array;
}
For Example:
$result=multisort($array,$sort_flags = DESC);

The simplest (but least efficient) would be a simple bubble sort
Pseudo code
for( $i from 0 to count($arr[total])):
for( $j from 0 to count(...)):
if($arr[total][$i] < $arr[total][$j]):
//SWAP VALUES AT i AND j
$this->swap($arr[total][$i],$arr[total][$j]);
$this->swap($arr[name][$i],$arr[name][$j]);
$this->swap($arr[reg_id][$i],$arr[reg_id][$j]);
// etc for all required fields
endif;
endfor;
endfor;
SWAP FUNCTION (PASS VALUES BY REFERENCE SO THEY WILL GET CHANGED)
function swap(&$i, &$j){
$t=$i;
$i=$j;
$j=$t;
}

Since those seem to be fields related to an entity, the best answer I can give you is to build better data structures. By example, you should build an Employee (or whatever entity you are representing there) class containing those fields:
class Employee
{
public $reg_id;
public $name;
public $test_w;
public $intr_w;
public $exp_w;
public $educ_w;
public $total;
}
and then keep an array of Employee's. What if you had another field that in turn was an array? I know my answer doesn't address the actual sorting, I'm just saying your way of keeping the data can get really dirty really quick.

I have sort array with the following function.
function msort($array, $key_s) {
$arraynew = $array;
foreach($array as $key=>$val){
if($key == $key_s){
for($i=0; $i<count($val); $i++){
for($j=0; $j<count($val); $j++){
if($val[$i] > $val[$j]){
$temp = $val[$i];
$val[$i] = $val[$j];
$val[$j] = $temp;
// swap all values
foreach($arraynew as $arrKey=>$arrVal){
$temp = $arraynew[$arrKey][$i];
$arraynew[$arrKey][$i] = $arraynew[$arrKey][$j];
$arraynew[$arrKey][$j] = $temp;
}
}
}
}
}
}
return $arraynew;
}

Related

Group and merge array row data based on one column

I have an array a bit like:
Array (
[1] => Array
(
[1] => 21
[2] => 3
[0] => Analyst
)
[2] => Array
(
[1] => 47
[2] => 8
[0] => Catalysis
)
[3] => Array
(
[1] => 1
[2] => 0
[0] => Biomaterials
)
[4] => Array
(
[3] => 12
[4] => 2
[0] => Analyst
)
[5] => Array
(
[5] => 12
[6] => 2
[0] => Analyst
)
...
However I would like to renumber those entries with the same [0] value so that I end up with
[1] => Array
(
[1] => 21
[2] => 3
[3] => 12
[4] => 2
[5] => 12
[6] => 2
[0] => Analyst
)
So far I've tried getting the [0] values out of the $results array by putting them in their own array and saying if you're already there then add [3] and [4] to where [1] and [2] are in a new array but it's not working.
$final = array();
$jArray = array();
foreach($results as $key => $result) {
if(!in_array($result[0],$jArray) && !empty($result[0])) {
$jArray[$i] = $result[0];
$i++;
}
}
for($x = 0; $x < count($results); $x++) {
$k = array_search($results[$x][0],$jArray);
if(!isset($results[$x][1]))
$final[$k][1] = $results[$x][1];
if(!isset($results[$x][2]))
$final[$k][2] = $results[$x][2];
if(!isset($results[$x][3]))
$final[$k][3] = $results[$x][3];
if(!isset($results[$x][4]))
$final[$k][4] = $results[$x][4];
if(!isset($results[$x][5]))
$final[$k][5] = $results[$x][5];
if(!isset($results[$x][6]))
$final[$k][6] = $results[$x][6];
}
Any simpler ways of doing this?
You can do this way...
$new_arr=array();
$arkeys = array_unique(array_map(function ($v){ return $v[0];},$arr));
foreach($arr as $k=>$arr1)
{
$new_arr[$arr1[0]][]=array_slice($arr1,0,count($arr1)-1);
}
foreach($arkeys as $v)
{
$new_arr[$v] = call_user_func_array('array_merge', $new_arr[$v]);
}
print_r($new_arr);
OUTPUT :
Array
(
[Analyst] => Array
(
[0] => 21
[1] => 3
[2] => 12
[3] => 2
[4] => 12
[5] => 2
)
[Catalysis] => Array
(
[0] => 47
[1] => 8
)
[Biomaterials] => Array
(
[0] => 1
[1] => 0
)
)
Working Demo
If you just want to group by the first element of the sub array, a single loop is enough:
$result = array();
foreach ($array as $sub_arr) {
$key = $sub_arr[0];
unset($sub_arr[0]);
if (!isset($result[$key])) {
$result[$key] = array();
}
$result[$key] += $sub_arr;
}
Here
$final = array();
foreach($results as $key => $result) {
if (!in_array($result[0], array_keys( $final ) ) && !empty($result[0])) {
$final[$result[0]] = array( $result[0] );
}
foreach($result as $k => $v) {
if ($k != 0 && isset($v)) {
$final[$result[0]][$k] = $v;
}
}
}

how to sum of two multidimensional array?

I am new in php. i need sum of two arrays but not getting right output.my arrays are coming in this way.
this is my first array.
Array
(
[1] => Array
(
[1] => Array
(
[-10] => 21787048.7293
[-5] => 21816115.9548
[-1] => 21839369.7352
[0] => 21845183.1803
[1] => 21850996.6254
[5] => 21874250.4058
[10] => 21903317.6313
)
)
[2] => Array
(
[2] => Array
(
[-10] => 21147607.6407
[-5] => 21496395.4105
[-1] => 21775425.6263
[0] => 21845183.1803
[1] => 21914940.7343
[5] => 22193970.9501
[10] => 22542758.7199
)
)
)
and this is second array.
Array
(
[1] => Array
(
[1] => Array
(
[-10] => 26101989.9443
[-5] => 26131057.1698
[-1] => 26154310.9501
[0] => 26160124.3952
[1] => 26165937.8403
[5] => 26189191.6207
[10] => 26218258.8462
)
)
[2] => Array
(
[2] => Array
(
[-10] => 25462548.8556
[-5] => 25811336.6254
[-1] => 26090366.8413
[0] => 26160124.3952
[1] => 26229881.9492
[5] => 26508912.1651
[10] => 26857699.9349
)
)
)
i need sum of these two arrays by keys.please help me out.
this is my code.my two arrays are $pretax_income, $earning.
foreach($pretax_income as $k=>$value)
{
foreach($value as $v=>$val)
{
foreach($val as $u=>$valArr) {
$comboarray[$elno] = $valArr[$k][$v][$u] + $earning[$k][$v][$u];
}
}
} print_r($comboarray);
function sum()
{
$identicalKeysArrays = func_get_args();
if (is_array($identicalKeysArrays[0])) {
$result = call_user_func_array('sum', array_map(function ($array) {
return $array[0];
}, $identicalKeysArrays));
if ($result) {
return $result;
}
}
if ($identicalKeysArrays[0]) {
$summed = array();
foreach ($identicalKeysArrays as $array) {
foreach ($array as $key => $value) {
$summed[$key] = ($summed[$key] ? $summed[$key] : 0) + $value;
}
}
return $summed;
}
}
$a = array(array(
'-1' => 23,
'2' => 2
));
$b = array(array(
'-1' => 3
));
var_dump(sum($a, $b));
Result:
array(2) { [-1]=> int(26) [2]=> int(2) }
Maybe something like this?
foreach($pretax_income as $key1=>$val1){
foreach($val1 as $key2=>$val2){
foreach($val2 as $key3=>$val3){
$comboarray[$key1][$key2][$key3]=$pretax_income[$key1][$key2][$key3]+$earning[$key1][$key2][$key3];
}
}
}

list and count elements in array php

I have the following array and am trying to loop through it with php, generate a list of the "Type" and count how many. The Type is the key, but there will be unique values such as Call, To-do, Meeting, Proposal, etc. My goal is to have the following out put:
Call 2
To-do 1
Meeting 3
Proposal 4
The above are not the values that will be output from the following array, but I wanted you to have an idea of what I am trying to accomplish. Please help!
Array (
[0] => Array (
[0] => Call
[Type] => Call
[1] => fxxxx#xxxxentllc.com
[EmailAddress] => xxxxr#xxxxentllc.com
[2] => 3xxxx00
[Phone] => 31xxxx00
[3] => 31xxxx871
[MobilePhone] => 31xxxx871
[4] => 102795
[CustomerID] => 102795
[5] => Nortxxxxal
[Company] => Noxxxxal
[6] => Frank
[FirstName] => Frank
[7] => Syxxxxer
[LastName] => Sxxxxter
[8] => 3
[Priority] => 3
[9] => invite to Haxxxxales for lunch
[Details] => invite to Hafxxxxales for lunch
[10] => 4503
[ActivityID] => 4503
[11] => 05/23/13
[DueDate] => 05/23/13
)
[1] => Array (
[0] => To-do
[Type] => To-do
[1] => fsxxxxer#summxxxxntllc.com
[EmailAddress] => fsxxxxer#summixxxxtllc.com
[2] => 315xxxx000
[Phone] => 3154xxxx0
[3] => 315xxxx1
[MobilePhone] => 315xxxx1
[4] => 102795
[CustomerID] => 102795
[5] => Norxxxxl
[Company] => Norxxxxcal
[6] => Frxxxxk
[FirstName] => Fxxxxk
[7] => Sxxxxr
[LastName] => Syxxxxer
[8] => 3
[Priority] => 3
[9] => find out who contact is for xxxxdical center
[Details] => find out who contact is foxxxxcal center
[10] => 4504
[ActivityID] => 4504
[11] => 05/23/13
[DueDate] => 05/23/13
)
)
This should do it:
$type_counts = array_count_values(array_map(function($x) {return $x['Type'];}, $array));
The array_map will return an array containing all the Type elements, then array_count_values will count the number of each of these and return this as an associative array.
something along the lines of:
foreach ($array as $key => $value) {
if (isset($result[$key])) {
$result[$key]++;
} else {
$result[$key] = 1;
}
}
if it is a muldi-dimensional array, just put another for each in there but that should give you an idea
$types = array();
foreach($array as $item) {
isset(${$item['Type']}) ? ${$item['Type']}++ : ${$item['Type']} = 1;
if(!in_array($item['Type'], $types) {
$types[] = $item['Type'];
}
foreach($types as $type) {
echo "$type ${$type}\n";
}
I think you can loop in your array and count each occorrence
$Call = 0;
$To_do = 0;
$Meeting = 0;
$Proposal = 0;
foreach($array as $data)
{
if($data['Type'] == 'Call')
{
$Call++;
} else if($data['Type'] == 'To-do')
{
$To_do++;
} else if($data['Type'] == 'Meeting')
{
$Meeting++;
} else if($data['Type'] == 'Proposal')
{
$Proposal++;
}
}
In this way you will have stored in each variable $Call $To_do $Meeting $Proposal its relative count
you can use (array_count_values($array));
http://php.net/manual/en/function.array-count-values.php
This gives count of all the keys in an array.
If you want only for the specific keys then use foreach loop
The one Petros mentioned is the best way to do it.
I would do something along the lines of:
$your_array = /* Your Array */
$types_count = array();
foreach ($your_array as $type_array){
$types_count[$type_array['Type']]++;
}

Sorting through array for to find match

I have two arrays like this
Array
(
[0] => MYU_MP1
[1] => 4cc00e5f580f00c2e54193fde7129608
[2] => da8bbfdb40be0dc2b3312ca1037f994a
[3] => d4cfaa8db24c4b81db506189360b6b99
)
Array
(
[0] => MYU_SC1
[1] => MYU_SC2
[2] => MYU_SF1
[3] => MYU_SC3
[4] => MYU_AD1
[5] => MYU_AD2
[6] => MYU_AD3
[7] => MYU_AD4
[8] => MYU_RC1
[9] => MYU_RC2
[10] => MYU_RC3
[11] => MYU_RC4
[12] => MYU_RC5
[13] => MYU_RC6
[14] => MYU_RC7
[15] => MYU_RC8
)
the first one aliased as "deliverable" and the other "non_deliverable"
and a third array
Array
(
[d8df18561040f3d9bd9868f5c5aaa7c2] => Array
(
[rowid] => d8df18561040f3d9bd9868f5c5aaa7c2
[id] => MYU_SC1
[qty] => 1
[price] => 500
[name] => WAEC Scratch Card
[service_image] => assets/img/waec.jpg
[service_category] => scratch_cards
[subtotal] => 500
)
the third array is aliased "cart_items"
[f68964856a61092d9a2566d024a0ba28] => Array
(
[rowid] => f68964856a61092d9a2566d024a0ba28
[id] => MYU_MP1
[qty] => 1
[price] => 210000
[name] => Apple iPhone 5 16gb
[service_image] =>
[service_category] => mobile-phones
[subtotal] => 210000
)
)
I have written a function that supposed to loop through the third array to determine if an "id" element of the third array is member of the first or second array
//sort through cart items
foreach ($cart_items as $key => $item) {
if(in_array($item['id'], $deliverables) && in_array($item['id'], $non_deliverables)) {
$deliverable = TRUE;
$non_deliverable = TRUE;
}
if(in_array($item['id'], $deliverables) && !in_array($item['id'], $non_deliverables)) {
$deliverable = TRUE;
}
if(in_array($item['id'], $non_deliverables) && !in_array($item['id'], $deliverables)) {
$non_deliverable = TRUE;
}
if($deliverable && $non_deliverable)
$type = "both";
if($non_deliverable)
$type = "non-deliverable";
if($deliverable)
$type = "deliverable";
}
return $type;
But when the third array has matches in both the 1st and 2nd array the function returns "deliverable". What am i not doing right?
function somefunction()
foreach ($cart_items as $key => $item) {
$deliverable = in_array($item['id'], $deliverables);
$non_deliverable = in_array($item['id'], $non_deliverables);
$type = "none";
if ($deliverable && $non_deliverable) {
$type = "both";
} elseif ($deliverable && !$non_deliverable) {
$type = "deliverable";
} elseif (!$deliverable && $non_deliverable) {
$type = "non-deliverable";
}
}
return $type;
}
Your sortorder is wrong. The check for $deliverable and $non_deliverable should be the last. Alternatively you could use an if-else-if-else structure.

Arrange PHP Multidimensional Array By Inner Index

How to arrange this array by last inner index ( 0, 1, 2 ) and get the value of the last inner index as the value of each second index:
Array
(
[text] => Array
(
[grid] => Array
(
[0] => 3
[1] => 4
[2] => 5
)
[image] => Array
(
[0] =>
[1] =>
[2] =>
)
[align] => Array
(
[0] => left
[1] => right
[2] => left
)
[title] => Array
(
[0] =>
[1] =>
[2] =>
)
[content] => Array
(
[0] =>
[1] =>
[2] =>
)
)
)
And have the results as below:
Array
(
[text] => Array
(
[0] => Array
(
[grid] => 3
[image] =>
[align] => left
[title] =>
[content] =>
)
[1] => Array
(
[grid] => 4
[image] =>
[align] => right
[title] =>
[content] =>
)
[2] => Array
(
[grid] => 5
[image] =>
[align] => left
[title] =>
[content] =>
)
)
)
This will do the work
function restructure($arr){
$newArr = array();
foreach($arr as $k => $v){
foreach($v as $k1 => $v1){
foreach($v1 as $k2 => $v2){
$newArr[$k][$k2][$k1] = $v2;
}
}
}
return $newArr;
}
As SiGanteng suggested, i dont see other ways than a for/foreach loop:
function buildArray($source, $key = false)
{
// Build the new array
$new_array = array();
// Define groups
$groups = $key === false ? array_keys($source) : array($key);
foreach($groups AS $group)
{
// Get the keys
$keys = array_keys($array[$group]);
// Count the values
$num_entries = count($array[$group][$keys[0]]);
for($i = 0; $i < $num_entries; $i++)
{
foreach($keys AS $key)
{
$new_array[$group][$i][$key] = $array[$group][$key][$i];
}
}
}
return $new_array;
}
This allow you to define the key you need to build; If not specified, the function build the array for every key.
This should work.
function formatit($arr) {
$new = array();
foreach($arr as $k=>$v) {
foreach($v as $k1=>$v1) {
$new[$k1][$k] = $v1;
}
}
return $new;
}
Tested. Call it as
$arr['text'] = formatit($arr['text']);
http://ideone.com/rPzuR

Categories