How to sort a multidimensional array by alphanumeric value? - php

I have an array like this below,
Array
(
[2] => Array
(
[id] => 75
[program] => Apr 2020-Nov 2020
)
[1] => Array
(
[id] => 73
[program] => Feb 2016-Aug 2020
)
[0] => Array
(
[id] => 72
[program] => May 2020-Dec 2020
)
)
The resultant array should be
Array
(
[1] => Array
(
[id] => 73
[current_program] => Feb 2016-Aug 2020
)
[2] => Array
(
[id] => 75
[current_program] => Apr 2020-Nov 2020
)
[0] => Array
(
[id] => 72
[current_program] => May 2020-Dec 2020
)
)
It should sort based on the year. I have tried to achieve by "strnatcasecmp", but the array is sorting by alphabet not by the numeric value in it
usort($programp, function($a, $b) {
return strnatcasecmp($a['program'], $b['program']);
});
Any help would be appreciated!
Thanks

You need to convert the first month and year into a timestamp, sort that thereby sorting the original:
foreach($programp as $values) {
$starts[] = strtotime(explode('-', $values['program'])[0]);
}
array_multisort($starts, $programp);
Before sorting the $starts array would look like this, easy to sort:
Array
(
[0] => 1585692000
[1] => 1454281200
[2] => 1588284000
)
You probably want some error checking to make sure $values['program'] is not empty etc...

//Sort indexes so the keys are 0,1,2 instead of 1,2,0
//This is important when sorting down below with asort()
$arr = array_values($arr);
//Go through every "program" (dateinterval in your array)
//and make a new array in the format year-monthnr
//Date parse returns the number of jan(1),feb(2),mar(3) etc..
$year_month = [];
foreach(array_column($arr,'program') as $key => $item) {
$year = explode(' ', explode('-',$item)[0])[1];
$month = date_parse(explode(' ', explode('-',$item)[0])[0])['month'];
$year_month[] = $year . '-' . $month;
}
//Sort with mainted indexes (keys)
asort($year_month);
//Create new array "mapped" keys to the original array $arr
$new_arr = [];
foreach($year_month as $key=>$item) {
$new_arr[] = $arr[$key];
}
Output of $new_arr would be:
Array
(
[0] => Array
(
[id] => 73
[program] => Feb 2016-Aug 2020
)
[1] => Array
(
[id] => 75
[program] => Apr 2020-Nov 2020
)
[2] => Array
(
[id] => 72
[program] => May 2020-Dec 2020
)
)

Related

Replace the values ​of one array based on the values in another array

I have the following array
$priceYear = Array (
[AZ] => Array
(
[1] => 2020
[2] => 2020
)
[BY] => Array
(
[0] => 2020
[1] => 2020
)
[CX] => Array
(
[1] => 2020
[2] => 2020
[3] => 2020
)
[DW] => Array
(
[106] => 2019
[107] => 2019
[108] => 2019
)
)
And another array with this
$array = Array (
[0] => Array
(
[YEAR] => 2018
[VALUE_AMDON] => 55
)
[1] => Array
(
[YEAR] => 2019
[VALUE_AMDON] => 57
)
[2] => Array
(
[YEAR] => 2020
[VALUE_AMDON] => 59
)
)
And I want to replace with the VALUE_AMDON if value from $priceYear == YEAR
So the output should look like this
$priceYear = Array (
[AZ] => Array
(
[1] => 59
[2] => 59
)
[BY] => Array
(
[0] => 59
[1] => 59
)
[CX] => Array
(
[1] => 59
[2] => 59
[3] => 59
)
[DW] => Array
(
[106] => 57
[107] => 57
[108] => 57
)
)
I'm doing it like this
function replace($var){
global $array;
for ($u=0; $u <sizeof($array) ; $u++) {
if ($var == $array[$u]['YEAR']){
return $array[$u]['VALUE_AMDON'];
}else{
return $var;
}
}
}
foreach ($priceYear as $key => $value) {
$priceYear[$key] = array_map('replace', $value);
}
But unfortunately it is not working, it is returning the initial array
If someone can help me, looks like the error is very dumb but i'm not seeing it :c
You can also do it with array functions like array_column and array_search check below:
$array_year = array_column($array, "YEAR");
foreach($priceYear as $key => $val){
foreach($val as $innerkey => $innerval){
// Below If year exist in $array_year function return key of $array_year else return false
$isExistKey = array_search($innerval, $array_year);
if($isExistKey !== FALSE){
$priceYear[ $key ][ $innerkey ] = $array[ $isExistKey ]["VALUE_AMDON"];
}
}
}
echo "<pre>";
print_r($priceYear);
Check the output here: https://paiza.io/projects/gUNihGow6-CWO0eqWpEtxg?language=php
Because there is no direct link between the keys of the arrays, the easiest way to do this is to use nested loops.
You just need to loop through your $priceYear array and check each of the "year" value acainst the YEAR value in $array. If they match, you can replace just that value in your $priceYear array.
The code below is commented to tell you what each line is doing:
// 1. loop through the nested arrays in $priceYear
foreach ($priceYear as $key => $price_years_array) {
foreach ($price_years_array as $index => $price_years_value) {
// 2. Create a variable to store the new value for the year in this $priceYear array,
// initialised to 0 (your specified default)
$new_year = 0;
// 3. check each year in your $array
foreach ($array as $replacement_values){
// 4. if $replacement_values has a YEAR and VALUE_AMDON...
// and $price_years_value matches the value in YEAR...
if( $replacement_values['YEAR'] && $replacement_values['VALUE_AMDON']
&& $replacement_values['YEAR'] == $price_years_value){
// 5. store this in our $new_year variable
$new_year = $replacement_values['VALUE_AMDON'];
}
}
// 6. after checking all years in $array, it we found a match it will be in $new_year
// otherwise it will still be 0.
// Now simple set this value - we can access this directly using $key and $index
$priceYear[$key][$index] = $new_year;
}
}
var_dump($priceYear);
Sample Data using years that don't exist:
$priceYear = array(
'AZ' => array( 1 => 2021, 2 => 2020), // <-- 2021 doesn't exist in $array
'BY' => array( 0 => 2020, 1 => 2016), // <-- 2016 doesn't exist in $array
'CX' => array(1 => 2020, 2 => 2020, 3 => 2020),
'DW' => array(106 => 2019, 107 => 2019, 108 => 2019)
);
$array = array(
array('YEAR' => 2018, 'VALUE_AMDON' => 55),
array('YEAR' => 2019, 'VALUE_AMDON' => 57),
array('YEAR' => 2020, 'VALUE_AMDON' => 59)
);
Output:
Array
(
[AZ] => Array
(
[1] => 0 // <-- value is 0 because year didn't exist in $array
[2] => 59
)
[BY] => Array
(
[0] => 59
[1] => 0 // <-- value is 0 because year didn't exist in $array
)
[CX] => Array
(
[1] => 59
[2] => 59
[3] => 59
)
[DW] => Array
(
[106] => 57
[107] => 57
[108] => 57
)
)

PHP converting simple array to more complex associative array

My selection from DB returns this:
Array
(
[0] => Array
(
[bin_full] => AA010101
[letter1_zone] => A
[letter2_aisle] => A
[letter34_bay] => 01
[letter56_level] => 01
[letter78_bin] => 01
)
[1] => Array
(
[bin_full] => AA010102
[letter1_zone] => A
[letter2_aisle] => A
[letter34_bay] => 01
[letter56_level] => 01
[letter78_bin] => 02
)
[2] => Array
(
[bin_full] => AA010201
[letter1_zone] => A
[letter2_aisle] => A
[letter34_bay] => 01
[letter56_level] => 02
[letter78_bin] => 01
)
As you can see, its basically the first item bin_full, being broken up into first letter, second letter, then next 2 numbers, next 2 numbers and finally the last 2 numbers. The pattern is the same, I need each level grouped together in an assoc array.
If I then do this, I'm mostly getting the result I want, but it needs a tweak and I'm not sure how to do that..
foreach ($data_full as $row) {
foreach ($row as $key2 => $value2) {
$data_array[$row['letter1_zone']][$row['letter2_aisle']][$row['letter34_bay']][$row['letter56_level']][$row['letter78_bin']] = $value2;
}
}
This results in:
Array
(
[A] => Array
(
[A] => Array
(
[01] => Array
(
[01] => Array
(
[01] => 01
[02] => 02
)
[02] => Array
(
[01] => 01
[02] => 02
)
[03] => Array
(
[01] => 01
)
)
)
)
)
I need the last array to be:
[0] => 01
[1] => 02
not
[01] => 01
[02] => 02
In full, I need this:
Array
(
[A] => Array
(
[A] => Array
(
[01] => Array
(
[01] => Array
(
[0] => 01
[1] => 02
)
[02] => Array
(
[0] => 01
[1] => 02
)
[03] => Array
(
[0] => 01
)
)
)
)
)
Thanks
All you have to do is replace this :
foreach ($data_full as $row) {
foreach ($row as $key2 => $value2) {
$data_array[$row['letter1_zone']][$row['letter2_aisle']][$row['letter34_bay']][$row['letter56_level']][$row['letter78_bin']] = $value2;
}
}
with this :
foreach ($data_full as $row) {
$data_array[$row['letter1_zone']][$row['letter2_aisle']][$row['letter34_bay']][$row['letter56_level']][] = $row['letter78_bin'];
}
so you replace the last index with a "add new element": []. It will first add index 0, then 1, then 2, etc...
$data_array[$row['letter1_zone']][$row['letter2_aisle']][$row['letter34_bay']][$row['letter56_level']][] = $value2;

How to combine three arrays with [0] as key into one

How can i turn this array:
Array ( [0] => 80 ) Array ( [0] => 20 ) Array ( [0] => 90 )
Into such array:
Array (
[0] => 80,
[1] => 20,
[2] => 90
);
Code:
$percentage_result = $percentage_query->result_array(); //output below:
Output:
Array
(
[0] => Array
(
[id] => 62
[list_id] => 55
[start_date] => 1459987200
[end_date] => 1459987200
[percentage] => 80
)
[1] => Array
(
[id] => 64
[list_id] => 55
[start_date] => 1459814400
[end_date] => 1459814400
[percentage] => 20
)
[2] => Array
(
[id] => 63
[list_id] => 55
[start_date] => 1459900800
[end_date] => 1459900800
[percentage] => 90
)
I want to save all of the [percentage] and get the highest one.
Doing this:
$null = array();
foreach ($percentage_result as $ptime) {
//Days between start date and end date -> seasonal price
$start_time = $ptime['start_date'];
$end_time = $ptime['end_date'];
$percentage_sm = explode(',', $ptime['percentage']);
$mrg = array_merge($null, $percentage_sm);
print_r($mrg);
$msg shows me:
Array
(
[0] => 80
)
Array
(
[0] => 20
)
Array
(
[0] => 90
)
You can do this in very simple way like this
$percentage_sm = array(); //define blank array
foreach ($percentage_result as $ptime) {
//Days between start date and end date -> seasonal price
$start_time = $ptime['start_date'];
$end_time = $ptime['end_date'];
$percentage_sm[] = $ptime['percentage']; //assign every value to array
}
print_r($percentage_sm);
Use array_merge()
$result = array_merge($arr1, $arr2, $arr3);
print_r($result);
If you want to get the highest percentage value from your $percentage_result array, then the easiest way to do it is
$maxPercentage = max(array_column($percentage_result, 'percentage'));
rather than trying to do something weird with array_merge
(PHP >= 5.5.0)
If you're running a lower version of PHP, then you can do something similar with
$maxPercentage = max(
array_map(
$percentage_result,
function ($value) { return $value['percentage']; }
)
);

Switch nested array values with keys, and reverse tally accordingly

I've taken a few photographs and I've tagged people as being in them. I have an array whose keys are photo_id's and whose values are arrays of person_id's tagged in the photograph:
Array
(
[19] => Array
(
[0] => 12
)
[21] => Array
(
[0] => 177
)
[26] => Array
(
[0] => 27
[1] => 4
)
[27] => Array
(
[0] => 27
[1] => 4
)
[28] => Array
(
[0] => 934
[1] => 935
[2] => 234
)
)
What I want is an array with the person_id's as keys and the photographs they are tagged in as values. For example, person 27 is in photographs 26 and 27. How would I go about creating this new array? Thank you so much!
You'll simply need to loop over your array and create a new array using the person_id as your new key and n number of entries which are your photo_ids:
$new_array = array();
foreach($original_array as $photo_id => $values) {
foreach($values as $person_id) {
// initialize array key if it doesn't already exist
if(!array_key_exists($person_id, $new_array)) {
$new_array[$person_id] = array();
}
// add photo id to the array
$new_array[$person_id][] = $photo_id;
}
}
Here's a demo: https://eval.in/147879
You can use a combination of array_walk() and in_array() to get what you need done:
$pictures = Array( 19 => [12], 21 => [177], 26 => [27,4], 27 => [27,4], 28 => [934,935,234] );
$included = [];
$person = 27;
//The following line is all you need
array_walk( $pictures, function(&$picture, $pictureId, $params) {
if( in_array( $params[1], $picture, TRUE ) )
array_push( $params[0], $pictureId );
}, [&$included, $person] );
print_r( $included );
Will print out:
Array
(
[0] => 26
[1] => 27
)
If you want to completely reverse the array, then you can use double foreach loops to iterate through them:
$pictures = [19 => [12], 21 => [177], 26 => [27,4], 27 => [27,4], 28 => [934,935,234] ];
$included = [];
foreach( $pictures as $pictureId => $picture ) {
foreach( $picture as $personId ) {
if( !isset( $included[$personId] ) )
$included[$personId] = [];
array_push( $included[$personId], $pictureId );
}
};
print_r( $included );
The result of this will print:
Array
(
[12] => Array
(
[0] => 19
)
[177] => Array
(
[0] => 21
)
[27] => Array
(
[0] => 26
[1] => 27
)
[4] => Array
(
[0] => 26
[1] => 27
)
[934] => Array
(
[0] => 28
)
[935] => Array
(
[0] => 28
)
[234] => Array
(
[0] => 28
)
)

Transform Array from Key/Value to Multi Dimensional

this may seem a rather trivial question, please excuse my ignorance. Still getting the hang of array manipulation...
I have a CakePHP app that is posting an array to my controller to be saved. I need to somehow reformat the sent array so that it may be processed properly by Cake's Save behaviour.
The array posted is:
Array (
[788] => Array ( [id] => 788 )
[787] => Array ( [id] => 787 )
[786] => Array ( [id] => 0 )
[785] => Array ( [id] => 0 )
[value_1] => 0
[analysed_date] => Array (
[month] => 08
[day] => 16
[year] => 2011
)
[job_id] => 34
)
Desired Array:
Array (
[0] => Array (
[id] => 788
[value_1] => 0
[analysed_date] => Array (
[month] => 08
[day] => 16
[year] => 2011
)
)
[1] => Array (
[id] => 787
[value_1] => 0
[analysed_date] => Array (
[month] => 08
[day] => 16
[year] => 2011
)
)
)
Thanks for taking the time to look.
EDIT:
I've just realised I omitted the fact that if the array has an [id] => 0 that it needs to be ignored. This was my primary stumbling block. Apologies. I hope the edit clarifies my problem better.
SOLVED
Thank you for your help guys. I was able to come up with the solution by myself. Here is what I came up with.
foreach($org_array as $key => $value){
if(is_array($value)){
if(isset($value['id'])){
if($value['id'] != 0) {
$data[$i] = array(
'id' => $value['id'],
'value_1'=> $value_1,
'analysed_date' => $date
);
$i++;
}
}
}
}
Something like this should work, but just for your example:
$array_keys = array_keys($org_array);
$new_array = array();
foreach ($array_keys as $key)
{
if (is_int($key))
{
$new_array[] = array(
"id" => $key,
"value1" => $org_array["value1"],
"analysed_date" => $org_array["analysed_date"]
);
// you might want to loop throught the original array to get all non-integer key values instead of hard-coding it
}
}
$main = Array (
[788] => Array ( [id] => 788 )
[787] => Array ( [id] => 787 )
[786] => Array ( [id] => 786 )
[785] => Array ( [id] => 785 )
[value_1] => 0
[analysed_date] => Array (
[month] => 08
[day] => 16
[year] => 2011
)
[job_id] => 34
)
$analysed_date = $main['analysed_date'];
$value1 = $main['value_1'];
$result = array();
$i=0;
foreach($main as $key=>$value)
{
if( is_numeric($key)
{
$result[$i]=array();
$result[$i]['id']=$key;
$result[$i]['value_1']=$value1;
$result[$i]['analysed_date']=$analysed_date;
$i++;
}
}

Categories