Populate array as per result of parent array - php

I have a parent array that contains
years as
1994,
1995,
1996,
1997,
1998,
1999,
2000,
2005
and on the other hand i am getting result from my db that returns year and count , Now, what i am trying to do is that an array being populated as per parent array (years) for the results being generated for something like following:
Results being Generated by sql
+----------------+
YEAR | Count
1994 | 16
1995 | 16
1996 | 16
+----------------+
The array should store following values as per check if sql query results contains result for year of parent array or not
1994 | 16
1995 | 16
1996 | 16
1997 | 0
1998 | 0
1999 | 0
2000 | 0
2005 | 0
Thanks,
Note I want the reuslt to be generated in an array as mentioned above because i have to pass these values to highcharts (For generating graph)

Depends how $years_db is built, Here an example:
$years = array(1994, 1995, 1996, 1997, 1998, 1999, 2000, 2005);
$years_db = array(1994 => 16, 1995 => 16, 1996 => 16);
$array_temp = array();
foreach ($years as $year)
{
/* if (in_array($year, array_keys($years_db)))
* $array_temp[$year] = $years_db[$year];
* else
* $array_temp[$year] = 0;
*/
// #gumbo suggestion is more efficient. THX!
$array_temp[$year] = isset($years_db[$year]) ? $years_db[$year] : 0;
}
output of $array_temp:
array (
1994 => 16,
1995 => 16,
1996 => 16,
1997 => 0,
1998 => 0,
1999 => 0,
2000 => 0,
2005 => 0,
)

Related

How to get all orders last 30 days with date range using codeigniter PHP?

Here is my table and I need to fetch all data from my MySQL database that will display the 30 days counting the total number of orders per day. And also there will be a date range.
Example 1: Current date is Aug 08, 2016. I need to display the last 30 days from Aug 08, 2016.
Order table
id | customer_id | num_of_order |date
---+-------------+--------------+--------
1 | 10001 | 1 | 2016-08-08 07:23:50
2 | 10002 | 4 | 2016-08-07 11:33:50
3 | 10003 | 2 | 2016-08-06 15:44:50 //same day
4 | 10001 | 5 | 2016-08-06 20:50:50 //same day
5 | 10004 | 3 | 2016-08-04 11:17:50
now for expected output it will display:
array (
[0] => array (
[date] => 2016-08-08
[total_orders] => 1
)
[1] => array (
[date] => 2016-08-07
[total_orders] => 4
)
[2] => array (
[date] => 2016-08-06
[total_orders] => 7
)
[3] => array (
[date] => 2016-08-05
[total_orders] => 0 //no orders but still need to include in the output
)
[4] => array (
[date] => 2016-08-04
[total_orders] => 3
)
//and so forth (July 09, 2016).....
)
Is there any PHP codeigniter code for this?
$this->db->select("DATE_FORMAT(date,'%Y-%m-%d') as covered_date,count(date(date)) AS total_order");
$this->db->from('order');
$this->db->where('date > DATE_SUB( "2016-08-08" , INTERVAL 30 DAY )');
$this->db->group_by("date(date)");
$query = $this->db->get();
$result = $query->result_array();
$start_date = date('Y-m-d', strtotime('-30 day', strtotime($end_date)));
$return = array();
while (strtotime($start_date) <= strtotime($end_date)) {
$return[] = $start_date;
$start_date = date("Y-m-d", strtotime("+1 day", strtotime($start_date)));
}
print_r($return);

Transpose query result set [duplicate]

This question already has answers here:
Transposing multidimensional arrays in PHP
(12 answers)
Chunk and transpose a flat array into rows with a specific number of columns
(3 answers)
Closed 5 months ago.
So I have a database with players names and their skill level.
It looks like this:
Id | Name | Level
1 | Peter | 24
2 | Andy | 23
...
24 | John | 1
The first player in the list with the highest level is the strongest one, and the last is the weakest.
I need to sort them in groups with 4 players, so if I have 24 people there will be 6 groups.
The way I need to sort it I call "zig-zag".
It goes like this:
Ag Bg Cg Dg Eg Fg
01 02 03 04 05 06
12 11 10 09 08 07
13 14 15 16 17 18
24 23 22 21 20 19
So the A group will consist of players: 1, 12, 13, 24.
B group of players: 2, 11, 14, 23.
C group of players: 3, 10, 15, 22 and so on.
It's easy to do it by hand, but how I could automate this sort with PHP language?
The groups should be array list (I think so) which could I easily put to the group tables in database.
The idea would be to:
Sort your starting data (or preferably, start with it sorted).
Split it into chunks, basically one per each of your rows.
Reverse the order of every other chunk.
Flip the matrix so you've got your groups - one per column instead of one per row.
Example:
// Basic sample data.
$players = range(1, 24);
// Sort them ascending if you need to.
sort($players);
// Make a matrix. 2d array with a column per group.
$matrix = array_chunk($players, ceil(count($players)/4));
// Reverse every other row.
for ($i = 0; $i < count($matrix); $i++) {
if ($i % 2) {
$matrix[$i] = array_reverse($matrix[$i]);
}
}
// Flip the matrix.
$groups = array_map(null, ...$matrix); // PHP 5.6 with the fancy splat operator.
//$groups = call_user_func_array('array_map', array_merge([null], $matrix)); // PHP < 5.6 - less fancy.
// The result is...
print_r($groups);
Output:
Array
(
[0] => Array
(
[0] => 1
[1] => 12
[2] => 13
[3] => 24
)
[1] => Array
(
[0] => 2
[1] => 11
[2] => 14
[3] => 23
)
[2] => Array
(
[0] => 3
[1] => 10
[2] => 15
[3] => 22
)
[3] => Array
(
[0] => 4
[1] => 9
[2] => 16
[3] => 21
)
[4] => Array
(
[0] => 5
[1] => 8
[2] => 17
[3] => 20
)
[5] => Array
(
[0] => 6
[1] => 7
[2] => 18
[3] => 19
)
)

Avoiding loops in a complex calculation with arrays

I have two arrays of numbers, one containing a lot of numbers, one only a few. There are no duplicates within or between arrays:
$all = range(1, 50);
$few = array(7, 11, 19, 27, 29, 36, 40, 43);
$many = array_merge(array_diff($all, $few));
I now want to calculate the differences between each of the "few" numbers and all of the "many" that follow it but come before the next of the "few". For example, among $many, only 28 falls between 27 and 29 from $few, so I want to calculate the difference between 28 and 27. No other differences to 27 are calculated, because no other $many fall between 27 and 29. For 19 from $few I will calculate the differences to 20, 21, 22, 23, 24, 25 and 26, because they all lie between 19 and the next number from $few, which is 27.
To calculate the differences, I use loops. Here is a somewhat simplified code (which ignores the fact that there is no index [$i + 1] for the last number in $few):
$differences = array();
for($i = 0; $i < count($few); $i++) {
foreach($many as $m) {
if($m > $few[$i] && $m < $few[$i + 1]) {
$differences[] = $m - $few[$i];
}
}
}
If I have huge arrays, the loops will take a long time to run. So:
Is there a better way to calculate the differences, without using loops?
The resulting $differences looks like this:
Array $many $few
( ↓ ↓
[0] => 1 // 8 - 7 = 1
[1] => 2 // 9 - 7
[2] => 3 // 10 - 7
[3] => 1 // 12 - 11
[4] => 2
[5] => 3
[6] => 4
[7] => 5
[8] => 6
[9] => 7
[10] => 1
[11] => 2
[12] => 3
[13] => 4
[14] => 5
[15] => 6
[16] => 7
[17] => 1
[18] => 1
[19] => 2
[20] => 3
[21] => 4
[22] => 5
[23] => 6
[24] => 1
[25] => 2
[26] => 3
[27] => 1
[28] => 2
)
My basic reasoning is that as a human, I don't see two arrays that I compare:
... 16 17 18 | 20 21 22 23 24 25 26 | 28 29 30 31 ...
exclude | include | exclude
19 (27)
But rather one number line that I go along from one number to the next, and when I meet one marked "few" I will calculate all the differences to each of the following numbers, until I meet another one marked "few":
... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ...
... m m m f m m m m m m m f m m m m ...
↑ ↑ ... ↑
start calculate stop
Because it is sorted, I don't have to go over the whole $many-array number by number for every number from $few. So can we somehow take the fact into account that the arrays are ordered? Or maybe build one array that contains the markers ("f", "m") and the numbers as keys? E.g.:
$all = array("drop this", "m", "m", "m", "m", "m", "m", "f", ...);
unset($all[0]); // drops the first element with index 0
Apart from the two calls to sort(), all you need is a single loop through $many.
// Input data provided in the question
$all = range(1, 50);
$few = array(7, 11, 19, 27, 29, 36, 40, 43);
$many = array_values(array_diff($all, $few));
// Display the values to see what we are doing
echo('$few = ['.implode(' ', $few)."]\n");
echo('$many = ['.implode(' ', $many)."]\n");
//
// The actual algorithm starts here
// Sort both $few and $many
// it works fast enough and it is required for the rest of the algorithm
sort($few);
sort($many);
// Be sure the last value of $few is larger than the last value of $many
// This is needed to avoid extra checking for the last element of $few inside the loop
if (end($few) < end($many)) {
array_push($few, end($many) + 1);
}
// Extract the first two items from $few
$current = array_shift($few);
$next = array_shift($few);
// This is the result
$differences = array();
// Run only once through $many, check each item against $next
// subtract $current from it; advance when $next was reached
foreach ($many as $item) {
// Skip the items smaller than the first element from $few
if ($item < $current) {
continue;
}
// If the next element from $few was reached then advance to the next interval
while ($next < $item) {
$current = $next;
$next = array_shift($few);
}
// Here $current < $item < $next
// This echo() is for debug purposes
echo('$current = '.$current.'; $item = '.$item.'; $next = '.$next.'; difference='.($item - $current)."\n");
// Store the difference
$differences[] = $item - $current;
}

Fetch Date and a String from another string

I have a bunch of strings like this, for example:
Time: 22:30 (25) | Date: 19 March 2011 | Contributor: Salesman
Now, I want to extract the date and the string after Contributor, i.e, Salesman.
Currently, I am using explode() function in PHP.
But the problem is, the string has many variations like:
Time: 22:30 (25) | Date: 19 March 2011
Time: 22:30 (25) | Date: 2011 | Contributor: Salesman
Time: 22:30 (25) | Contributor: Salesman
Time: 22:30 (25) | Date: 2011
I want something that works perfect for all the variations. Where a field is unavailable, I shall consider it as NULL. For full date I need to store the date in database, and for only year I shall save the year.
Suggest me some code for this problem, or a regular expression in PHP if this problem can be solved through it.
Time:.*?\|\s*(?:Date:\s*([0-9a-zA-Z ]+))?\|?\s*(?:Contributor:\s*([a-zA-Z0-9 ]+))?
Try this.This will only give groups available.
See demo.
http://regex101.com/r/nG1gU7/18
You could try something like this:
$string = 'Time: 22:30 (25) | Date: 19 March 2011';
function str_func($string, $key, $remove_key = FALSE)
{
$string = trim($string);
if ($string[strlen($string) - 1] !== '|') {
$string .= '|';
}
$pos = strpos(strtolower($string), strtolower($key) . ':');
if ($pos !== FALSE) {
$return = strstr(substr($string, $pos), '|', true);
return ($remove_key) ? trim(substr($return, strlen($key) + 1)) : $return;
} else {
return NULL;
}
}
So just pass it the string and 'Time' or 'Contributor' (and optionally whether you'd like the key to be removed) e.g.
//Will return Time: 22:30 (25)
echo str_func($string, 'time');
//Will remove 'date: ' from the returned string
echo str_func($string, 'date', TRUE);
Hope this helps!
I think you want something like this,
^.*?\|\s*\K(?:Date:\s*((?:\d{2}\s*\S+)?\s*\d{4})\s*\|?)?\s*(?:Contributor:\s*(\S+))?
DEMO
Group index 1 contains the value of Date: field and group index 2 contains the value of Contributor: field.
Code:
<?php
$data = <<< EOT
Time: 22:30 (25) | Date: 19 March 2011
Time: 22:30 (25) | Date: 2011 | Contributor: Salesman
Time: 22:30 (25) | Contributor: Salesman
Time: 22:30 (25) | Date: 2011
EOT;
$regex = '~^(?:.*?\|\s*)(Date:\s*((?:\d{2} \S+ )?\d{4}))?(?:\s\|\s*)?(Contributor:\s*(\S+))?\s*$~m';
preg_match_all($regex, $data, $matches);
print_r($matches);
?>
Output:
Array
(
[0] => Array
(
[0] => Time: 22:30 (25) | Date: 19 March 2011
[1] => Time: 22:30 (25) | Date: 2011 | Contributor: Salesman
[2] => Time: 22:30 (25) | Contributor: Salesman
[3] => Time: 22:30 (25) | Date: 2011
)
[1] => Array
(
[0] => Date: 19 March 2011
[1] => Date: 2011
[2] =>
[3] => Date: 2011
)
[2] => Array
(
[0] => 19 March 2011
[1] => 2011
[2] =>
[3] => 2011
)
[3] => Array
(
[0] =>
[1] => Contributor: Salesman
[2] => Contributor: Salesman
[3] =>
)
[4] => Array
(
[0] =>
[1] => Salesman
[2] => Salesman
[3] =>
)
)

Array merge while keeping the same order?

I've got an array that is an array of arrays, ordered by date, as so:
Array
(
[1379167200] => Array
(
[110] => Introduction to Banking | Saturday, September 14, 2013 - 10:00am
)
[1380376800] => Array
(
[71] => Saving, Investing, Debt | Saturday, September 28, 2013 - 10:00am
)
[1381588200] => Array
(
[72] => Setting Personal Goals | Saturday, October 12, 2013 - 10:30am
)
[1382796000] => Array
(
[74] => Type of Account: What's Right for You? | Saturday, October 26, 2013 - 10:00am
)
[1384009200] => Array
(
[81] => Creating an Account: Learning to Budget | Saturday, November 09, 2013 - 10:00am
)
)
I want to keep the ordering (i.e., ordered by date), but preferably only include the most inner array items in a single array. Like so:
Array
(
[110] => Introduction to Banking | Saturday, September 14, 2013 - 10:00am
[71] => Saving, Investing, Debt | Saturday, September 28, 2013 - 10:00am
[72] => Setting Personal Goals | Saturday, October 12, 2013 - 10:30am
[74] => Type of Account: What's Right for You? | Saturday, October 26, 2013 - 10:00am
[81] => Creating an Account: Learning to Budget | Saturday, November 09, 2013 - 10:00am
)
How would this be possible? Would I need to convert the integers to strings or something?
I absolutely need to maintain the ordering by date, but I also need to maintain the relationship between the integer key and the value, both are used.
Iterate through array, create new array:
$newArray = Array();
foreach($array as $row) { // $row is subarray
$value = current($row); // first value in subarray "Itroduction to ..."
$key = key($row); // first key in subarray 101, 71, 72
$newArray[$key] = $value;
}
Demo;
http://codepad.viper-7.com/dd3PLV
Docs:
http://php.net/manual/en/function.current.php
http://php.net/manual/en/function.key.php

Categories