PHP Multidimensional Array problem - php

iam trying to build a multidimensional array.
public function saveRateTemplateData($RateTemplateInfo)
{
$RateTemplateID = $RateTemplateInfo['id'];
$Zones = $RateTemplateInfo['premium_zones'];
//$ZoneZipCodeIDs[] = array();
for ($n = 1; $n <= $RateTemplateInfo['premium_zones']; $n++) {
$ZoneNum = 'zone' . $n;
$ZipCodeArray = explode(",",$_POST[$ZoneNum]);
$ZipCodeIDs=array();
foreach ($ZipCodeArray as $v) {
$v = intval(trim($v));
if (strlen($v) == 5) {
array_push($ZipCodeIDs, $this->addZipCode($v));
} else {
echo "it isnt 5";
}
}
}
}
so what iam trying to do is make an array of an array. so this is how its supposed to look
Array
(
[1] => Array
(
[0] => 34
[1] => 31
[2] => 23
)
[2] => Array
(
[0] => 18
[1] => 4
[2] => 35
[3] => 1
)
)
i have tried numerous ways it doesnt work
basically i want it in this format VarName[ZoneNumbers][ZipCodeID]
so i can loop through it later on. so i can print like this $VarName[$n] then a array of all zipcodeID will print for Zone Number 1 in this case it will print 34,31,23

public function saveRateTemplateData($RateTemplateInfo)
{
$RateTemplateID = $RateTemplateInfo['id'];
$zones = array(); // you weren't using this so I'll use it to hold the data
for ($n = 1; $n <= $RateTemplateInfo['premium_zones']; $n++) {
$ZoneNum = 'zone' . $n;
// create an array under the zone number for holding the IDs
$zones[$n] = array();
$ZipCodeArray = explode(",",$_POST[$ZoneNum]);
foreach ($ZipCodeArray as $v) {
$v = (int) trim($v);
if (strlen($v) == 5) {
$zones[$n][] = $this->addZipCode($v);
} else {
// use exceptions for exceptional circumstances
throw new RuntimeException(sprintf('Invalid zone ID "%s"', $v));
}
}
}
return $zones;
}

Related

How to parse an array in PHP to fill NULL as average between two closest values

Im trying to parse an array in PHP to fill Null values as averages between the closest two values before inserting into MySQL (5). I have currently tried the below code but the code moves the pointer for the entire array when I call next($value['wind']).
f_data:
(
[2019-05-06 09:00:00] => Array
(
[temp] => 50
[wind] => 10
[rain] => 50
)
[2019-05-06 10:00:00] => Array
(
[temp] => 65
)
[2019-05-06 11:00:00] => Array
(
[temp] => 70
[wind] => 8
[rain] => 30
)
)
code thus far:
foreach ($f_data as $key => $value) {
$f_weather_date = $key;
$future_weather = $value['temp'];
if ($value['wind'] > 0) {
$f_wind = $value['wind'];
$f_wind_last = $f_wind;
} else {
$f_wind = $f_wind_last;
$x = 0;
$f_wind_next = 0;
for ($x = 0; $f_wind_next = 0; $x++) {
$f_wind_next = next($value['wind']);
return $x;
}
$f_wind = ($f_wind_next + $f_wind_last) / $x;
}
if ($value['rain'] > 0) {
$f_rain = $value['rain'];
$f_rain_last = $f_rain;
} else {
$f_rain = $f_rain_last;
}
$sql = "INSERT INTO `Table` (`Date`, `Temp`, `Wind`, `Rain`) VALUES ('$f_weather_date', $future_weather, $f_wind, $f_rain)";
mysqli_query($conn, $sql);
}
Expected results would return [wind] => 9 and [rain] => 40 at 10:00:000
First extract the keys and then iterate with int key. This way you can calculate the average easily.
Consider:
$keys = array_keys($f_data);
$arr = array_values($f_data);
foreach($arr as $k => &$v) {
if (!isset($v['rain']) { //you can do the same for wind
$v = ($arr[$k -1]['rain'] + $arr[$k +1]['rain']) /2;
}
}
Now return the original keys with:
$f_data = array_combine($keys, $arr);
Notice you need to take care of case the last eleme t is missing data and when 2 neighbors elements missing data

Split php array to group when value is range or no

I have array value like this :
$src = array(3,15,16,17,18,20,25,7);
How can i split it into :
array(
[0] => 3,
[1] => array([0] => 15, [1] => 18),//when value is range get start and end
[2] => 20,
[3] => 25,
[4] =>
);
Check this code. If your sequence/range difference is based on only next numbers, then this code would work for you.
<?php
$src = array(3,15,16,17,18,20,25,7);
$tot = count($src);
$resarr = array();
$st = $ed = '';
for($i=0;$i<$tot;$i++){
if($st==''){
if(isset($src[$i+1]) && $src[$i+1] == $src[$i]+1){
$st = $src[$i];
}
}
else{
if(!isset($src[$i+1]) || $src[$i+1] != $src[$i]+1){
$ed=$src[$i];
}
}
if($st=='' && $ed==''){
$resarr[] = $src[$i];
}
elseif($st!='' && $ed!=''){
$resarr[] = array($st,$ed);
$st = $ed='';
}
}
print_r($src);
echo "<pre>";print_r($resarr);echo "</pre>";
?>
Also phpfiddle example is here http://phpfiddle.org/lite/code/k7c4-wvdg. Keep practice write your own logic.
// Make copy of array with shifting to one item.
// And, to save array length, add one element to the end of the array.
// It can be any number, but not continue sequence.
// I add the last item of source array
$src1 = $src;
array_shift($src1);
array_push($src1,end($src));
// Then subtract corresponding items of array
$temp = array_map(function ($i, $j) { return $j-$i; }, $src, $src1);
// Look at arrays
// $src 3, 15, 16, 17, 18, 20, 25, 7
// $temp 12, 1, 1, 1, 2, 5, -18, 0,
// As you can see, all elements of sequences, but the last, has 1 in `temp` array.
// Therefore, we just need to collect the result
$sarr = false;
$result = array();
for($i=0; $i<count($src); $i++) {
if($temp[$i] == 1) {
if(! $sarr) {
$sarr = $src[$i];
}
}
else {
if(! $sarr) {
$result[] = $src[$i];
}
else {
$result[] = [$sarr, $src[$i]];
$sarr = false;
}
}
}
print_r($result);
Test it there
I added some values just to cover edge cases. Comments explain.
<?php
$src = array(3,4,15,16,17,18,20,25,7,8);
$res = [];
$start = null;
//Rather than make a counter use a for loop
for($i=0; $i < count($src); $i++){
//Make sure i+1 is not bigger than array
//If current index value + 1
//Euqals the next index value we have a range
if($i+1 < count($src) && $src[$i]+1 == $src[$i+1]){
if($start === null){
$start = $i;
}
//Once the range is over we can use the current index as end
} elseif($start !== null){
$res[] = array($src[$start], $src[$i]);
$start = null;
$end = null;
//There was never a range.
} else {
$res[] = $src[$i];
}
}
echo "<pre>";
print_r($res);
Results:
Array
(
[0] => Array
(
[0] => 3
[1] => 4
)
[1] => Array
(
[0] => 15
[1] => 18
)
[2] => 20
[3] => 25
[4] => Array
(
[0] => 7
[1] => 8
)
)

Multidimensional array sum values

I have following function to sum multidimensional array values.
// summing values of multidimensional array
function getSum($array, $path = array()){
// process second argument:
foreach ($path as $key) {
if (!is_array($array) || !isset($array[$key])) {
return 0; // key does not exist, return 0
}
$array = $array[$key];
}
if(is_array($array)) {
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
$sum = 0;
foreach ($iterator as $key => $value) {
$sum += $value;
}
} else{
$sum = $array;
}
return $sum;
}
I'm using the function like this:
$array = array();
$array['one']['green'][20] = 20;
$array['one']['blue'][20] = 5;
$array['one']['blue'][30] = 10;
getSum($array,['one','green']); // 20
getSum($array,['one','blue',20]); // 5
Now I have a problem if I don't want to for example set any spesific color because I want that script sums all values from category 20 from all colours.
So it should be working like this:
getSum($array,['one','*',20]); // 25
Thanks for your help!
Here is example of my array:
Array (
[1] => Array (
[AREA I] => Array (
[20] => 1
[25] => 0
[30] => 0 )
[AREA II] => Array (
[20] => 0
[30] => 0 )
[AREA III] => Array (
[20] => 2
[30] => 0 )
[AREA IV] => Array (
[20] => 0
[30] => 3 )
[AREA V] => Array (
[20] => 4
[25] => 0
[30] => 3 )
)
[2] => Array (
[AREA I] => Array (
[20] => 0
[30] => 0 )
[AREA II] => Array (
[20] => 0
[30] => 0 )
)
)
And here is example of my getSum call:
getSum($visitsandinfosact,['*','*',20]); // should print 7
Recursive Function
I was not sure if ['one','*'] should give 45 but if it should just return 0 you just have to remove the else if (empty($filterList) && is_array($value) && $first == "*")condition. All values which are not arrays are just converted to int via intval and added to the sum. If you wanna use float then use floatval instead of intval
function getSum($array, $filterList = array('*')) {
$sum = 0;
$first = array_shift($filterList);
foreach ($array as $key => $value) {
if ($key == $first || $first == "*") {
if (is_array($value) && !empty($filterList)) {
$sum += getSum($value, $filterList);
} else if (empty($filterList) && is_array($value)) {
$sum += getSum($value, array("*"));
} else if (empty($filterList)) {
$sum += intval($value);
}
}
}
return $sum;
}
echo getSum($array,['one','*',20], 10) . "\n"; // 25
echo getSum($array,['one','*','*',20]) . "\n"; // 10
echo getSum($array,['one','*']) . "\n"; // 45
echo getSum($array) . "\n"; // 45
Input Array
$array = array();
$array['one'] = array();
$array['one']['green'] = array();
$array['one']['green'][20] = 20;
$array['one']['blue'] = array();
$array['one']['blue'][20] = 5;
$array['one']['blue'][30] = 10;
$array['one']['orange']['red'][20] = 10;
Output
Only the numbers are outputted but just added the input params for better understanding.
25 // (['one','*',20])
10 // (['one','*','*',20])
45 // (['one','*'])
45 // no filterList
In short, you need a recursive function to add in wildcard "endpoints". You might as well use the same recursive nature to cover the addition as well.
The following should do what you're wanting:
// summing values of multidimensional array
function getSum(&$array, $path = array()){
$sum = 0;
if(is_int($array) and empty($path)) // return value if int
$sum = $array;
else if(is_array($array)){ // else add recurred values
if(empty($path)){
foreach($array as $value)
$sum += getSum($value);
} else {
$key = array_shift($path);
if($key=='*'){
foreach($array as $value)
$sum += getSum($value, $path);
} else {
if(isset($array[$key]))
$sum += getSum($array[$key], $path);
}
}
}
return $sum;
}
Test:
$array['one'] = array();
$array['one']['green'] = array();
$array['one']['green'][20] = 20;
$array['one']['blue'] = array();
$array['one']['blue'][20] = 5;
$array['one']['blue'][30] = 10;
$array['one']['orange']['red'][20] = 10;
echo getSum($array,['one','*',20]); // 25
echo getSum($array,['one','*','*',20]); // 10
echo getSum($array,['one','*']); // 45
Happy coding

Get path from adjacency list data

I have an array (data from adjacency table) and it looks like:
Array
(
[0] => Array
(
[id] => 1
[name] => Anniversary
[parent] => 0
)
[1] => Array
(
[id] => 12
[name] => New arrives
[parent] => 1
)
[2] => Array
(
[id] => 13
[name] => Discount
[parent] => 12
)
[3] => Array
(
[id] => 6
[name] => Birthday
[parent] => 0
)
)
And I'm looking for the way to retrieve my path by ID;
For example: getPath(13): Anniversary->New arrives->Discount;
For example: getPath(12): Anniversary->New arrives;
For example: getPath(1): Anniversary;
For example: getPath(6): Birthday;
How can I do this?
Thanks!
function getpath($id, $arr, $level = 0) {
$result = array();
foreach($arr as $key => $value){
if($id == $value['id']){
$result[] = $value['name'];
$id = $value['parent'];
if($id != 0){
$result = array_merge($result, getpath($id, $arr, $level+1));
}else{
break;
}
}
}
return $level ? $result : implode('->',array_reverse($result));
}
echo getpath(13,$arr);
Consider this array,
$input = [
['id'=>1, 'name'=>'Anniversary', 'parent'=>0],
['id'=>12, 'name'=>'New arrives', 'parent'=>1],
['id'=>13, 'name'=>'Discount', 'parent'=>12],
['id'=>6, 'name'=>'Birthday', 'parent'=>0]
];
and this function,
function path($element_id, $input, $ids = [])
{
if(!$ids) // for performance, make this once and pass it around
{
$ids = array_column($input, 'id'); // array containing only 'id's of $input
}
$current_key = array_search($element_id, $ids); // search for $input variable's current key
unset($ids[$current_key]); // unsetting used keys to make above array search faster next time
$current_element = $input[$current_key]; // get current element as array from $input
$names[] = $current_element['name']; // create an array containing current element
if($current_element['parent'] != 0) // check if current element have parent
{
$names[] = path($current_element['parent'], $input, $ids); // call this function, let it return string, append it to $names
}
return implode(' ⟶ ', array_reverse($names)); // make final return, seprate by ⟶
}
Reading echo path(13, $input); will return
Anniversary ⟶ New arrives ⟶ Discount
Here is minified version of the same function
function path($a,$b,$c=[]){if(!$c){$c=array_column($b,'id');}$d=array_search($a,$c);unset($c[$d]);$e=$b[$d];$f[]=$e['name'];if($e['parent']!=0){$f[]=path($e['parent'],$b,$c);}return implode(' ⟶ ',array_reverse($f));}
Thanks to code reviewers Loufylouf and Quill
$find = 13;
$path = array();
function FindById ($arr, $find) {
$k = null;
foreach($arr as $key => $item)
if ($item['id'] == $find)
{ $k = $key; break; }
return $k;
}
if ( false === ($k = FindById($arr, $find))) die("not found");
while (true) {
array_unshift($path, $arr[$k]['name']);
if( ! $arr[$k]['parent']) break;
if(false === ($k = FindById($arr, $arr[$k]['parent']))) die("illegal structure");
}
echo implode('->', $path);

Adding count values in a temporary array

I am counting the difference between two days in inside a foreach loop.
foreach ($result as $key => $value) {
# code...
//$temp[$value->user_id]=$value->user_id;
$count_dates=daysBetween($value->user_source_history_added,$current_date);
$tmp_array[$count_dates][] = $count_dates;
}
On debugging tmp_array, I get something like this.
Array
(
[0] => Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 0
[5] => 0
[6] => 0
)
[1] => Array
(
[0] => 1
)
[3] => Array
(
[0] => 3
[1] => 3
[2] => 3
[3] => 3
)
)
Now I want to count the number of 0's, 1's, 2's, 3's, etc. So for now there are 7 0's and 1 1's and 4 3's.
How do I get the count of all these numbers and how do I limit it that I get only the count till Array 20??
I tried this:
foreach($tmp_array as $tmp_val)
{
count($tmp_val)
}
But I get the count of main array that is 3
Update if($count_array<=20){}
This is a general solution, it will take in consideration any number in you have in your $temp array and it will store this number as his record in this array
$found_numbers=array();
$results=array();
$count_array=0;
foreach($tmp_array as $first_array)
{ $count_array++;
foreach($first_array as $second_array)
{
if($count_array<=20){
if (in_array($second_array, $found_numbers)) {
$results[$second_array][0]++;
}
else{
array_push($found_numbers,$second_array);
$results[$second_array] = array();
array_push($results[$second_array],1);
}
}
}
}
//to get how many you have number n in your array you have only to type print($results[n][0]);
print($results[0][0]); //will give you 7
print($results[n][0]); //will give the record of the number n in your array
If you want the count of everything added together:
$count = 0;
foreach($tmp_array as $tmp_subarray)
{
foreach($tmp_subarray as $tmp_val) {
if($count < 20) {
$count++;
}
}
}
If you want the amount of 1s, 2s, 3s, etc:
$count = array();
foreach($tmp_array as $tmp_subarray)
{
foreach($tmp_subarray as $tmp_val) {
if($count[$temp_val]) {
$count[$temp_val]++;
} else {
$count[$temp_val] = 1;
}
}
}
This will count all the values of an array no matter how many dimensions assuming the values are arrays or numbers. This will run until the main array has reached $key == 20.
$total = 0;
function addToTotal($number) {
glob $total;
$total = $total + $number;
}
function countArrayValues($array) {
foreach($array as $key => $value) {
if(is_array ($value) {
countArrayValues($value);
} else {
addToTotal($value);
}
}
}
$mainArray; // <-- your array;
foreach($mainArray as $key => $value) {
if($key <= 20) {
countArrayValues($value);
} else {
break;
}
}
echo $total;
Try this :
$array_number_of_numbert = array();
foreach($tmp_array as $tmp_val_num => $tmp_val)
{
$array_number_of_numbert[$tmp_val_num]= $tmp_val;
}
for($i = 0; $i <=20; $i++)
{
if(isset($array_number_of_numbert[$i])) echo count($array_number_of_numbert[$i])." ". $i."'s\n";
}

Categories