Filling php array that has missing values - php

I've a series of arrays with values that goes from 1 to 5. Almost every array has missing values, some even dont have any values. My objective is to fill the missing values with 0. All those arrays are stored into a multidimensional array.
My array looks like:
Array
(
[1] => Array
(
[0] => 1
[1] => 2
[2] => 3
)
[2] => Array
(
[0] => 1
[1] => 5
)
[3] => Array
(
[0] => (this array has no values)
)
[4] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
etc...
)
How it should be:
Array
(
[1] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 0
[4] => 0
)
[2] => Array
(
[0] => 1
[1] => 0
[2] => 0
[3] => 0
[4] => 5
)
[3] => Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 0
)
[4] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
etc...
)
Any help would be appriciated!

For each of your subarrays loop through the numbers 1 to 5, and if that value exists set its key to be one less than its value:
$newarray = array();
foreach($arr as $key => $subarr) {
for ($i = 1; $i <= 5; $i++) {
if (in_array($i, $subarr)) $newarray[$key][$i - 1] = $i;
else $newarray[$key][$i - 1] = 0;
}
}
Where $newarray is your output and $arr is your input array.

You may want to note that PHP does not truly do multidimensional arrays. It only allows you to relate 2 flat arrays together which is not true multidimensionality.
This does not work and will produce results described above.
$menu[1] = "My Training"; //not $menu[1][0]
$menu[1][1] = "To Do List";
$menu[1][2] = "Catalog";
$menu[1][3] = "Self-Report";
$menu[1][4] = "Completions";
$menu[2] = "Manager";
$menu[2][1] = "Direct Reports";
$menu[2][2] = "Incompletes";
$menu[2][3] = "Completions";
$menu[3] = "Instructor";
$menu[3][1] = "My Classes";
$menu[3][2] = "Printables";
$menu[3][3] = "Qualifications";
This does work.
$menu[1] = "My Training"; //not $menu[1][0]
$submenu[1][1] = "To Do List";
$submenu[1][2] = "Catalog";
$submenu[1][3] = "Self-Report";
$submenu[1][4] = "Completions";
$menu[2] = "Manager";
$submenu[2][1] = "Direct Reports";
$submenu[2][2] = "Incompletes";
$submenu[2][3] = "Completions";
$menu[3] = "Instructor";
$submenu[3][1] = "My Classes";
$submenu[3][2] = "Printables";
$submenu[3][3] = "Qualifications";
$submenu is only related to $menu through the first key number as there are no first dimension values to $submenu.

Something like this (array_pad() won't do the trick). $myArray is your source array. Completed array is returned in $result:
$result = array();
foreach( $myArray as $subKey=>$subArray ) {
for( $i=0; $i<5; $i++ ) {
if( isset( $subArray[$i] )) {
$result[$subKey][$i] = $subArray[$i];
} else {
$result[$subKey][$i] = 0;
}
}
}
Note, we do copy of the array. You cannot fill array in-place.

It's been many years since I wrote any PHP but something like this might do the trick I guess?
for($i = 0; $i < 5; $i++)
{
if(empty($myArray[$i])
{
$myArray[$i] = 0;
}
}

Related

PHP Array Swap in dynamic input

I have two dynamic arrays of integer, one thing that I wanna do is swap value inside my array-based on input.
For example my two arrays:
$myArray_a =
Array
(
[0] => 21306000
[1] => 50627412
[2] => 2560227681
[3] => 2796924085
[4] => 0
[5] => 0
)
$myArray_b =
Array
(
[0] => 505909732
[1] => 400831144
[2] => 2693575413
[3] => 3072271817
[4] => 5277000763
[5] => 4944000763
)
And my expected output was when the input = 3, array B index number 4 and 5 swap to array A in the same index.
$output =
Array
(
[0] => 21306000
[1] => 50627412
[2] => 2560227681
[3] => 2796924085
[4] => 5277000763
[5] => 4944000763
)
I want to switch, is there an easy way to do this? Or will it require a loop + creating a new array?
Provided your are using an numeric index, you could leverage array_slice
This will create an array with the first four entries, then append the second array skipping existing keys.
$count = 4; // which is 3 + 1
$a = [21306000,50627412,2560227681,2796924085,0,0];
$b = [505909732,400831144,2693575413,3072271817,5277000763,4944000763];
$output = array_slice( $a, 0, $count ) + $b;
//Array
//(
// [0] => 21306000
// [1] => 50627412
// [2] => 2560227681
// [3] => 2796924085
// [4] => 5277000763
// [5] => 4944000763
//)
You can do it with,
$index = 3;
$result = $B;
for($i = 0; $i<= $index; $i++){
$result[$i] = $A[$i];
}
You can use foreach
foreach($myArray_a as $k => &$v){
empty($v) && isset($myArray_b[$k]) ? ($v = $myArray_b[$k]) : '';
}
DEMO :- https://3v4l.org/nRj68
<?php
$a = [2,3,4,5,0,0];
$b = [20,30,40,50,60,70];
$counter = 0;
$out = array_map(function($m, $n ) use (&$counter)
{
return $counter++>3 ? $n : $m;
}, $a, $b);
var_export($out);
Output:
array (
0 => 2,
1 => 3,
2 => 4,
3 => 5,
4 => 60,
5 => 70,
)

PHP - get array element between a range in multidimensional array

I have a multidimensional array. I want to get array element which value is greater than 2 and less than 17. My Array is given below:
Array
(
[4] => Array
(
[0] => 17
[1] => 15
[2] => 12
)
[5] => Array
(
[0] => 16
)
[2] => Array
(
[0] => 3
[1] => 1
)
[1] => Array
(
[0] => 2
)
)
I want output like below:
Array
(
[4] => Array
(
[0] => 17
[1] => 15
[2] => 12
)
[5] => Array
(
[0] => 16
)
[2] => Array
(
[0] => 3
[1] => 1
)
)
Please help me how can I do it easy & fast method.
You can use a nested array filter.
$result = array_filter($outer_array, function($inner_array) {
return array_filter($inner_array, function($number) {
return $number > 2 && $number < 17;
});
});
Then inner array filter will result in an empty array being passed to the outer array filter if no values are found in the specified range. The empty array will evaluate to false in the outer filter callback, eliminating that array from the result.
Demo at 3v4l.org.
Generally, we want you to show what you have tried before we'll write code for you, but this one's on the house. For future reference, include some code snippets along with your question to avoid getting downvoted.
$output = array();
for($i = 0; $i < count($arr); $i++)
{
$use = false;
for($j = 0; $j < count($arr[$i]); $j++)
{
if($arr[$i][$j] > 2 and $arr[$i][$j] < 17)
{
$use = true;
break;
}
}
if($use)
$output[] = $arr[$i];
}
return $output;

Error of index while filling an array in php

The first step is to create an new array with zeros. This is the code:
$amounts = [];
$row = [];
for($a = 0; $a < count($receipts_with_total); $a++){
for($b = 0; $b < count($taxes); $b++){
$row[$b] = 0;
}
$amounts[] = $row;
}
Then, i proceede to fill the array with values. The problem is, for some reason i don't know, it adds some indexs.
The code to fill the array is the next one:
//We calculate all the taxes amounts
for($i = 0; $i < count($receipts_with_total); $i++){
$this_receipt = $receipts_with_total[$i];
//We get all the taxes for each receipt
$taxes = $this_receipt->taxes;
for($j = 0; $j < count($taxes); $j++){
$this_tax = $taxes[$j];
if($this_tax->name == "IVA 21%"){
$amounts[$i][$j] = round((($this_tax->value * $total[$i]) / 100), 2);
}
elseif($this_tax->name == "IVA 10.5%"){
$amounts[$i][$j+1] = round((($this_tax->value * $total[$i]) / 100), 2);
}
else {
$amounts[$i][$j+2] = round((($this_tax->value * $total[$i]) / 100), 2);
}
}
}
And the outputs are:
Creacion
Array ( [0] => Array ( [0] => 0 [1] => 0 [2] => 0 ) [1] => Array ( [0] => 0 [1] => 0 [2] => 0 ) [2] => Array ( [0] => 0 [1] => 0 [2] => 0 ) [3] => Array ( [0] => 0 [1] => 0 [2] => 0 ) )
Modelo
Array ( [0] => Array ( [0] => 0 [1] => 257.46 [2] => 61.3 ) [1] => Array ( [0] => 0 [1] => 40.36 [2] => 9.61 ) [2] => Array ( [0] => 80.73 [1] => 40.36 [2] => 9.61 ) [3] => Array ( [0] => 211.05 [1] => 105.53 [2] => 0 ) )
Lleno
Array ( [0] => Array ( [0] => 0 [1] => 257.46 [2] => 0 [3] => 61.3 ) [1] => Array ( [0] => 0 [1] => 40.37 [2] => 0 [3] => 9.61 ) [2] => Array ( [0] => 80.73 [1] => 0 [2] => 40.37 [4] => 9.61 ) [3] => Array ( [0] => 211.05 [1] => 0 [2] => 105.53 ) )
The first output is the new array with zeros. The second one is an example of as should be the final array with the calculate numbers. The last one is the array really i get.
As you can see, the index in bold represent the errors. For example, the value "61.3" is in fourth position in the first array, instead of third, it would be the correct.
Thanks!
Remove the +1 and +2 from the code.
Just
$amounts[$i][$j]=...
in all cases.
Because if i.e.
$j=2;
it may be become 3 in your code $j+1
My answer just pick that part of your question:
The problem is, for some reason i don't know, it adds some indexs.
I guess you want to show the "IVA 21" always in the 0 index in subarray and "IVA 10.5" always in the 1 index in sub array, and so on...? So you don't have to +1 or +2 in the index...cuz $j has already been increment in the for loop...
Or if you don't know which comes first or maybe you will have more option later, do not use a for loop. Use php foreach and keep +1 manually
$j = 0;
foreach ($taxes as $$this_tax) {
if ($this_tax->name == 'IVA 21%') {
$amounts[$i][$j] = round((($this_tax->value * $total[$i]) / 100), 2);
} elseif ($this_tax->name == 'IVA 10.5%') {
$amounts[$i][$j + 1] = round((($this_tax->value * $total[$i]) / 100), 2);
} else {
$amounts[$i][$j + 2] = round((($this_tax->value * $total[$i]) / 100), 2);
}
//myabe +3 later...
}
Or why not just use a static number like 0,1,2 if you always know the length of $taxes and where you gonna put for your results. You can even create conts like:
define('IVA21', 0); // const IVA21 = 0;
define('IVA105', 1);
// ... more define
//for loop starts
if ($this_tax->name == 'IVA 21%') {
$amounts[$i][IVA21] = round((($this_tax->value * $total[$i]) / 100), 2);
}

PHP: How to reorder a two dimensional array

This is how $myArray looks like:
Array
(
[0] => Array
(
[month] => 1
[atual] => 0.00
)
[1] => Array
(
[month] => 2
[atual] => 11970.99
)
[2] => Array
(
[month] => 3
[atual] => 2888.00
)
[3] => Array
(
[month] => 5
[atual] => 1500.00
)
)
I want to "fill the gaps" of the months. That is, for those months, where we have no data (4,6,8,9,10,11,12), I want the [atual] to be zero.
I tried:
$novo=array();
for ($i=1; $i <=12 ; $i++) {
$mes=$myArray[$i-1]['month'];
$atual=$myArray[$i-1]['atual'];
if(!$mes){
$novo[$i]=0;
} else{
$novo[$i]=$atual;
}
};
But this is returning:
Array
(
[1] => 0.00
[2] => 11970.99
[3] => 2888.00
[4] => 1500.00
[5] => 0
[6] => 0
[7] => 0
[8] => 0
[9] => 0
[10] => 0
[11] => 0
[12] => 0
)
[edit] now i see you have another problem, your $myArray indexes aren't matching the months.
$myArray(
array('month' => 1, 'atual' => 0.00),
array('month' => 2, 'atual' => 11970.99),
array('month' => 3, 'atual' => 2888.00),
array('month' => 5, 'atual' => 1500.00)
)
for($i = 1; $i <= 12; $i++){
$novo[$i] = 0;
}
foreach($myArray as $item){
$novo[$item['month']] = $item['atual'];
}
print_r($novo);
This worked:
$novo=array_fill(1,12,0);
for ($i=1; $i <=12 ; $i++) {
$mes=$myArray[$i-1]['month'];
$atual=$myArray[$i-1]['atual'];
$novo[$mes]=$atual;
};
With this code you get the month 1 in position 1 (not in position 0);
Also you only search in the array one time.
It's not a beautiful solution but...
$my_array = array(
array('month'=>3,'actual'=>100)
);
$results =array();
for($i=1;$i<13;$i++){
$results[$i] = 0;
}
foreach($my_array as $a){
$results[$a['month']] = $a['actual'];
}
print_r($results);
PHP has several functions that deal with sorting arrays, and here is a comparison of array's sorting functions
I didn't fully understand your question in the first response. This code should work for you. First we will create a temporary array just to hold the month and the data in an accessible format. Then we create your array :
$temp=array();
// Populate the temp array
foreach ($myArray as $row) {
if (is_array($row) && isset($row["month"])) {
$temp[$row["month"]] = $row["atual"];
}
}
// Create novo array
for ($i=0; $i <12 ; $i++) {
$novo[$i]["month"] = $i+1;
if (array_key_exists($i+1, $temp)) {
$novo[$i]['atual'] = $temp[$i+1];
} else {
$novo[$i]['atual'] = 0;
}
}

php split array between two values

i have an array like:
Array ( [0] => #!A1#DC [1] => #IMSR102.71/74.82 [2] => #HV50 [3] => #PR7/7/ [4] => #RX0 [5] => #ERN/1//0 [6] => #Q2 [7] => #!A1#DC [8] => #IMSR102.50/74.82 [9] => #HV40 [10] => #PR5/5/ [11] => #RX0 [12] => #ERN/1//1 [13] => #Q2 etc etc with hundreds o values
i get this array from a file (with the function file($filename) ) and i need to split it in many subarray.
"!A1#DC" this is the beginning of a series of values ​​that ends with #Q2 but the number of the values between the beginning and the end is not always the same and the only 2 values that are same are the two given ("!A1#DC" for the beginning and "#Q2" for the end)
how can i get somethings like this?
Array (
[0] => Array ( [0] => #!A1#DC [1] => #IMSR102.71/74.82 [2] => #HV50 [3] => #PR7/7/ [4] => #RX0 [5] => #ERN/1//0 [6] => #Q2 )
[1] => Array (
[1] => #!A1#DC [2] => #IMSR102.50/74.82 [3] => #HV40 [4] => #PR5/5/ [5] => #RX0 [6] => #ERN/1//1 [7] => #Q2 etc etc
could you please help me?
thanks
Loop through an array. When you meet starting value, store it's index. When you meet ending value, use array_slice() to extract the part between the last pair of starting and ending values, store this part into another array.
$source = array (
'#!A1#DC',
'#IMSR102.71/74.82',
'#HV50',
'#PR7/7/',
'#RX0',
'#ERN/1//0',
'#Q2',
'#!A1#DC',
'#IMSR102.50/74.82',
'#HV40',
'#PR5/5/',
'#RX0',
'#ERN/1//1',
'#Q2',
);
$dest = array();
$startValue = '#!A1#DC';
$endValue = '#Q2';
$startIndex = 0;
foreach ( $source as $index => $value ) {
if ( $value === $startValue ) {
$startIndex = $index;
} else
if ( $value === $endValue ) {
$dest[] = array_slice($source, $startIndex, $index - $startIndex + 1);
}
}
print_r($dest);
Basically you need to loop through each element of $input, collecting those within START and END elements into a separate array:
$input = array("#!A1#DC", "A", "B", "#Q2");
$values = array();
$current = 0;
define("START", "#!A1#DC");
define("END", "#Q2");
for ($i = 0; $i < count($input); $i++) {
if ($input[$i] == END) {
// Ignore any elements after this point until we see START
$current = null;
} else if ($input[$i] == START) {
// Create a new current collection array
$current = count($values);
$values[$current] = array();
} else {
// Store the value if we are collecting
if ($current !== null) {
$values[$current][] = $input[$i];
}
}
}

Categories