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";
}
Related
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
i have two arrays
$value_array = array('50','40','30','20','10');
$customer = array('300','200','100');
i want to distribute the value array to customers based on the value of customers that is taken as limit.adding values by checking it wont cross the limit that is 300 , 200 and 100.
but customer array not working one direction it should work first forward and then backward like that
i want to produce an array in form of
Array
(
[0] => Array
(
[0] => 50
)
[1] => Array
(
[0] => 40
[1] => 10
)
[2] => Array
(
[0] => 30
[1] => 20
)
)
After completing customer loop first time it should start from last to first. both array count will change , i mean count.
value array should check 50 -> 300 , 40->200, 30->100 then from last ie, 20 ->100, 10->200 etc.
I tried like
$i = 0;
while($i < count($customer)){
foreach($value_array as $k=>$value){
$v = 0;
if($value <= $customer[$i]){
$customer2[$i][] = $value;
unset($value_array[$k]);
$v = 1;
}
if($v ==1){
break;
}
}
//echo $i."<br/>";
if($i == (count($customer)-1) && (!empty($value_array))){
$i = 0;
$customer = array_reverse($customer, true);
}
$i++;
}
echo "<pre>";
print_r($customer2);
$valueArray = array('50','40','30','20','10','0','-11');
$customer = array('300','200','100');
function parse(array $valueArr, array $customerArr)
{
$customerCount = count($customerArr);
$chunkedValueArr = array_chunk($valueArr, $customerCount);
$temp = array_fill(0, $customerCount, array());
$i = 0;
foreach ($chunkedValueArr as $item) {
foreach ($item as $key => $value) {
$temp[$key][] = $value;
}
$temp = rotateArray($temp);
$i++;
}
// if $i is odd
if ($i & 1) {
$temp = rotateArray($temp);
}
return $temp;
}
function rotateArray(array $arr)
{
$rotatedArr = array();
//set the pointer to the last element and add it to the second array
array_push($rotatedArr, end($arr));
//while we have items, get the previous item and add it to the second array
for($i=0; $i<sizeof($arr)-1; $i++){
array_push($rotatedArr, prev($arr));
}
return $rotatedArr;
}
print_r(parse($valueArray, $customer));
returns:
Array
(
[0] => Array
(
[0] => 50
[1] => 0
[2] => -11
)
[1] => Array
(
[0] => 40
[1] => 10
)
[2] => Array
(
[0] => 30
[1] => 20
)
)
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
Let's say I have following array:
Array
(
[0] => Array
(
[0] => a
[1] => 1
)
[1] => Array
(
[0] => b
[1] => 8
)
[2] => Array
(
[0] => c
[1] => 16
)
[3] => Array
(
[0] => d
[1] => 21
)
....
)
Numbers in inner array are generated randomly from range (0, 100) and they don't repeat.
I would like to create a loop, which will iterate from 0 to 100 and check if loop iteration is equal to inner number of above array. Excepted result is array with 100 elements:
Array
(
[0] => const
[1] => a
[2] => const
[3] => const
[4] => const
[5] => const
[6] => const
[7] => const
[8] => b
[9] => const
[10] => const
.
.
[16] => c
[17] => const
.
.
[21] => d
[22] => const
[23] => const
.
.
)
What I need is something like:
for ($i=0; $i < 100; $i++) {
if($i === $name[$i][1]) {
$new_array[] = $name[$i][0];
} else {
$new_array[] = 'const';
}
}
But I can't get it working, thus I need some help.
I am not an English native speaker, so hopefully you understand what I would like to achieve. Thanks for any help.
you need a nested loop like:
for ($i=0; $i < 100; $i++):
$found = false;
foreach($name as $array):
if($array[1] === $i):
$found = true;
$new_array[] = $array[0];
endif;
endforeach;
if(!$found):
$new_array[] = 'const';
endif;
endfor;
The reason it doesn't work is because each time $i is incremented you're trying to make a match in $name[$i], and not checking all of the arrays in $name, the simplest solution I can think of (and to perform the least number of iterations) would be to do something like:
$new_array = array();
foreach ($name as $n) {
$new_array[$n[1]] = $n[0];
}
for ($i=0; $i<100; $i++) {
if (!isset($new_array[$i])) {
$new_array[$i] = 'const';
}
}
ksort($new_array);
So first of all, loop through your $name array, and set up your $new_array with the the key => value pair (eg. [1] => 'a', [8] => 'b'), then in the for loop just check if the key ($i) has already been set, and if not, set it with the value 'const'. Finally, sort the $new_array by its keys.
The number of iterations in this example is count($name) + 100, whereas a nested loop for example would be 100 * count($name).
use
for ($i=0; $i < 100; $i++) {
if($i === $name[$i][1]) {
$new_array[$i] = $name[$i][0];
}
else{
$new_array[$i] = 'const';
}
}
for ($i = 0; $i < count($name); ++$i) {
if ($name[$i][1] === $i) {
$name[$i] = $name[$i][0];
} else {
$name[$i] = 'const';
}
}
Why do u use Identical operator instead of Equal
for ($i=0; $i < 100; $i++) {
if($i == $name[$i][1]) {
$new_array[] = $name[$i][0];
} else {
$new_array[] = 'const';
}
}
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;
}