I want to group results by month, to be precise Sum of total prices for each month, but i don't understand how i can divide months, then Sum price for each month.
This is required for morris chart like this
$data2[] = array(
'y' => $month,
'a' => price,
'b' => ''
);
I was using before query to get this results and was a easy way to do it, but now with code is different story.
Any help with explanation of how each segment of code is work will be so nice, so i can avoid problems like this one in future.
I need something like this :
$month = [May, June];
$price = [Sum of all prices for May, Sum of all prices for June];
This is a code :
$monthsArray = array();
// get all dates in array
foreach ($array as $key) {
// convert dates to short format, month-year -> Jun-18
$monthsArray[] = date('M-y', strtotime($key['time']));
}
$months = array();
foreach ($monthsArray as $date) {
$mon = substr($date, 0, 6);
if (!in_array($mon, $months)) array_push($months, $mon);
}
foreach ($months as $m) {
// final array for chart
$data2[] = array('y'=>$m, 'a'=>'', 'b'=>'');
}
$morris = json_encode($data2);
This is array i have
Array
(
[0] => Array
(
[price] => -1835.25
[time] => 2018-05-29 16:53:38
)
[1] => Array
(
[price] => -1743.52
[time] => 2018-05-29 16:53:39
)
[2] => Array
(
[price] => -4445.55
[time] => 2018-05-31 13:21:04
)
[3] => Array
(
[price] => -34647.04
[time] => 2018-05-31 18:29:43
)
[4] => Array
(
[price] => 16888.41
[time] => 2018-06-01 15:05:24
)
[5] => Array
(
[price] => 14369.05
[time] => 2018-06-07 14:44:21
)
[6] => Array
(
[price] => -49579.69
[time] => 2018-06-11 09:14:42
)
[7] => Array
(
[price] => -33300.94
[time] => 2018-06-08 23:50:29
)
[8] => Array
(
[price] => 4413.21
[time] => 2018-06-12 07:15:52
)
[9] => Array
(
[price] => 2724.69
[time] => 2018-06-12 07:15:46
)
[10] => Array
(
[price] => 10224.03
[time] => 2018-06-08 14:00:13
)
[11] => Array
(
[price] => -797.92
[time] => 2018-06-08 13:54:08
)
[12] => Array
(
[price] => -25157.34
[time] => 2018-06-11 11:31:31
)
[13] => Array
(
[price] => 2701.6
[time] => 2018-06-11 14:32:08
)
[14] => Array
(
[price] => 2038.92
[time] => 2018-06-12 07:15:48
)
[15] => Array
(
[price] => -10541.58
[time] => 2018-06-15 10:35:58
)
)
EDIT:
I manage to group months as you can see in updated code and now i am getting only 2 results as i should be, now its just a issue with SUM of data for each month.
This is what i am getting in console
0: {y: "May-18", a: "", b: ""}
1: {y: "Jun-18", a: "", b: ""}
Hello I am trying to search for an hour based on the current date with the following function:
$key = array_search($todayday, array_column($days, 'date', 'hours'));
Where $todayday is equal to today day which comes from the sever day date.
the Array $days is:
Array
(
[0] => Array
(
[date] => 01
[hours] => 0
)
[1] => Array
(
[date] => 02
[hours] => 8
)
[2] => Array
(
[date] => 03
[hours] => 16
)
[3] => Array
(
[date] => 04
[hours] => 24
)
[4] => Array
(
[date] => 05
[hours] => 32
)
[5] => Array
(
[date] => 06
[hours] => 40
)
[6] => Array
(
[date] => 07
[hours] => 40
)
... etc....
while $todaydate is equal to 1,2,3,4,5 it works. but for 6 and 7 does not return anything. Any help is welcome to resolve this issue. Thanks
I suspect that since date = 6 and 7 have the same value of hours this is why it does not return anything but the question is how to return it actually.
Your supposition is correct, you can not have duplicate keys. Use the key from the search and then access hours:
$key = array_search($todayday, array_column($days, 'date'));
$hours = $days[$key]['hours'];
Or shorter:
$hours = $days[array_search($todayday, array_column($days, 'date'))]['hours'];
In the case where the indexes are not 0 based and sequential, use array_values() to re-index:
$days = array_values($days);
$key = array_search($todayday, array_column($days, 'date'));
$hours = $days[$key]['hours'];
I'm running through all of the array functions on php.net and unable to figure this out.
Essentially I want to take these two arrays:
Array
(
[0] => stdClass Object
(
[month] => October
[year] => 2015
[credit] => 1000.00
)
[1] => stdClass Object
(
[month] => September
[year] => 2015
[credit] => 200.00
)
)
Array
(
[0] => stdClass Object
(
[month] => October
[year] => 2015
[debit] => 2000.00
)
[1] => stdClass Object
(
[month] => August
[year] => 2015
[debit] => 50.00
)
)
...and have the output look like this:
Array
(
[0] => stdClass Object
(
[month] => October
[year] => 2015
[credit] => 1000.00
[debit] => 2000.00
)
[1] => stdClass Object
(
[month] => September
[year] => 2015
[credit] => 200.00
[debit] => 0
)
[2] => stdClass Object
(
[month] => August
[year] => 2015
[credit] => 0
[debit] => 50.00
)
)
I'm looked to merge "month" and "year" and combine the other keys, using a default value if the key doesn't exist. Any guidance?
Assuming $debits and $credits are the arrays shown in your question, I would approach it like this:
First loop over the credits, inserting them into the new "combined" array and adding a default value for debit as you go.
foreach ($credits as $credit) {
$credit->debit = 0.00; // provide a default value for debit
$combined[$credit->year . $credit->month] = $credit;
}
Then loop over the debits. Since there is the possibilities that entries will already be there from credits, there needs to be a check for this. This part should update existing values inserted from credits, or insert new values if there is no existing value.
foreach ($debits as $debit) {
if (isset($combined[$debit->year . $debit->month])) {
// update the debit if the entry already exists
$combined[$debit->year . $debit->month]->debit = $debit->debit;
} else {
// otherwise create a new entry with a default value for credit
$debit->credit = 0.00;
$combined[$debit->year . $debit->month] = $debit;
}
}
// If you need the results to be numerically indexed, you can use array_values
$numerically_indexed = array_values($combined);
This question already has answers here:
How can I sort arrays and data in PHP?
(14 answers)
Closed 2 months ago.
I need some help about sorting a multiple array.
This is what I got:
Array (
[ALU0000001] =>
Array ( [0] => Array ( [period] => 2012 [codCurse] => S12-2030 [idPersona] => ALU0000001 [date] => 2012-04-02 [amount] => 238.00 [active] => X )
[1] => Array ( [period] => 2012 [codCurse] => S12-2030 [idPersona] => ALU0000001 [date] => 2012-05-02 [amount] => 238.00 [active] => X )
[2] => Array ( [period] => 2012 [codCurso] => S12-2030 [idPersona] => ALU0000001 [date] => 2012-06-02 [amount] => 238.00 [active] => X )
[3] => Array ( [period] => 2013 [codCurso] => S12-2030 [idPersona] => ALU0000001 [date] => 2013-01-02 [amount] => 238.00 [active] => X )
[ALU0000005] =>
Array ( [0] => Array ( [period] => 2013 [codCurse] => S13-2010 [idPersona] => ALU0000005 [date] => 2013-03-01 [amount] => 225.00 [active] => X )
[1] => Array ( [period] => 2013 [codCurse] => S13-2010 [idPersona] => ALU0000005 [date] => 2013-03-02 [amount] => 333.00 [active] => X )
[2] => Array ( [period] => 2013 [codCurse] => S13-2010 [idPersona] => ALU0000005 [date] => 2013-04-02 [amount] => 333.00 [active] => X )
I need to sort multiarray by period date to get something like this
Y M D
2012 2012-04-02 ALU00000001 .....
2012 2012-05-02 ALU00000005 .....
2012 2012-06-01 ALU00000001 .....
2013 2013-01-01 ALU00000001 .....
2013 2013-06-01 ALU00000001 .....
2013 2013-12-24 ALU00000005 .....
Thanks
As danp says you will need a custom sort function using PHP usort.
You execute this in Codeigniter using the syntax;
usort($data_array, array('controller', 'sort_function'));
function sort_function($a, $b)
{
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
Considering the main array keys don't do much (because they're already contained within the values by the date key) you can safely ignore them. So first you want to collect all the values into a single array to be able to sort later:
$allItems = array();
foreach ($outputArr as $arr) { // $outputArr should be the name of your array
$allItems = array_merge($allItems,array_values($arr));
}
Then you need to sort the array values by the date keys:
function sortByDate($a,$b) {
$d1 = strtotime($a['date']);
$d2 = strtotime($b['date']);
return $d1 == $d2 ? 0 : ($d1 > $d2 ? 1 : -1);
}
usort($allItems,'sortByDate');
// and there you go.
print_r($allItems);
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Sorting multidimensional array in PHP
How can I sort by key in a multidimensional array?
For instance, below is the array I print from my db, where the latest comes first - December, November, October, etc and 2011, 2010, 2009, etc
Array
(
[0] => Array
(
[URL] => september 2011
[Title] => September 2011
[Date] => 8
[Month] => 9
[Year] => 2011
)
[1] => Array
(
[URL] => january 2011
[Title] => January 2011
[Date] => 1
[Month] => 2
[Year] => 2011
)
[2] => Array
(
[URL] => february 2011
[Title] => February 2011
[Date] => 4
[Month] => 1
[Year] => 2011
)
[3] => Array
(
[URL] => november 2011
[Title] => November 2011
[Date] => 23
[Month] => 11
[Year] => 2010
)
[4] => Array
(
[URL] => april 2011
[Title] => April 2011
[Date] => 23
[Month] => 4
[Year] => 2010
)
)
But I need it to be like this, October, November, December, etc and 2011, 2010, 2009, etc - note the months are sorted by the oldest comes first but the years are still sorted by the latest comes first.
So the array should be sorted like this,
Array
(
[2] => Array
(
[URL] => february 2011
[Title] => February 2011
[Date] => 4
[Month] => 1
[Year] => 2011
)
[1] => Array
(
[URL] => january 2011
[Title] => January 2011
[Date] => 1
[Month] => 2
[Year] => 2011
)
[0] => Array
(
[URL] => september 2011
[Title] => September 2011
[Date] => 8
[Month] => 9
[Year] => 2011
)
[4] => Array
(
[URL] => april 2010
[Title] => April 2010
[Date] => 23
[Month] => 4
[Year] => 2010
)
[3] => Array
(
[URL] => november 2010
[Title] => November 2010
[Date] => 23
[Month] => 11
[Year] => 2010
)
)
Is that possible?
Generic solution to sort arrays of arrays with multiple keys
Based on my answer to this question, here is a very generic solution that you can use in lots of situations.
Limitation: Requires PHP >= 5.3 to work, due to the presence of anonymous functions.
New and improved, now with descending sort support
function make_comparer() {
$criteriaNames = func_get_args();
$comparer = function($first, $second) use ($criteriaNames) {
// Do we have anything to compare?
while(!empty($criteriaNames)) {
// What will we compare now?
$criterion = array_shift($criteriaNames);
// Used to reverse the sort order by multiplying
// 1 = ascending, -1 = descending
$sortOrder = 1;
if (is_array($criterion)) {
$sortOrder = $criterion[1] == SORT_DESC ? -1 : 1;
$criterion = $criterion[0];
}
// Do the actual comparison
if ($first[$criterion] < $second[$criterion]) {
return -1 * $sortOrder;
}
else if ($first[$criterion] > $second[$criterion]) {
return 1 * $sortOrder;
}
}
// Nothing more to compare with, so $first == $second
return 0;
};
return $comparer;
}
How to use it
To sort by year ascending:
uasort($array, make_comparer('Year'));
To sort by year ascending, then by month ascending:
uasort($array, make_comparer('Year', 'Month'));
To sort by year descending, then by month ascending:
uasort($array, make_comparer(array('Year', SORT_DESC), 'Month'));
This last one is what you 're after.
Assuming that the data you would have provided in your question would have been actually correct (taking Year, Month, Date as base to create a sort on), you can first index the array by those values and the sort the main array. I'm just writing it, otherwise you might misread the output of the Demo, the URL/Titles do not correspond to the numerical values given, but it just works:
// create an index by date
foreach($data as $k=>$v)
{
$index[$k] = sprintf('%04d-%02d-%02d', $v['Year'], $v['Month'], $v['Date']);
}
// sort data based on the index
array_multisort($index, SORT_DESC, $data);
How about:
Data:
$arr = Array (
Array (
'URL' => 'september 2011',
'Title' => 'September 2011',
'Date' => 8,
'Month' => 9,
'Year' => 2011,
),
Array (
'URL' => 'january 2011',
'Title' => 'January 2011',
'Date' => 1,
'Month' => 2,
'Year' => 2011,
),
Array (
'URL' => 'february 2011',
'Title' => 'February 2011',
'Date' => 4,
'Month' => 1,
'Year' => 2011,
),
Array (
'URL' => 'november 2011',
'Title' => 'November 2011',
'Date' => 23,
'Month' => 11,
'Year' => 2010,
),
Array (
'URL' => 'april 2011',
'Title' => 'April 2011',
'Date' => 23,
'Month' => 4,
'Year' => 2010,
),
);
code:
function compare($a, $b) {
if ($a['Year'] == $b['Year']) {
return ($a['Month'] - $b['Month']);
} else {
return ($b['Year'] - $a['Year']);
}
}
usort($arr, 'compare');
print_r($arr);
output:
Array
(
[0] => Array
(
[URL] => february 2011
[Title] => February 2011
[Date] => 4
[Month] => 1
[Year] => 2011
)
[1] => Array
(
[URL] => january 2011
[Title] => January 2011
[Date] => 1
[Month] => 2
[Year] => 2011
)
[2] => Array
(
[URL] => september 2011
[Title] => September 2011
[Date] => 8
[Month] => 9
[Year] => 2011
)
[3] => Array
(
[URL] => april 2011
[Title] => April 2011
[Date] => 23
[Month] => 4
[Year] => 2010
)
[4] => Array
(
[URL] => november 2011
[Title] => November 2011
[Date] => 23
[Month] => 11
[Year] => 2010
)
)