Inserting calculated values during a for each loop - php

I have an array that looks like this.
Array
(
[0] => Array
(
[0] => 1
[1] => 500
[2] => 800
)
[1] => Array
(
[0] => 1
[1] => 100
[2] => 200
)
[2] => Array
(
[0] => 1
[1] => 300
[2] => 400
)
)
I want to use a foreach loop (not a function) to do several things. First I just want to subtract subelement [1] from subelement [2] to generate sub element [3] and then insert subelement3 back into the output array. See below:
$output=
Array
(
[0] => Array
(
[0] => 1
[1] => 500
[2] => 800
[3] => 300
)
[1] => Array
(
[0] => 1
[1] => 100
[2] => 200
[3] => 100
)
[2] => Array
(
[0] => 1
[1] => 400
[2] => 250
[3] => 150
)
)
To do the above I am using the for each loop below to generate the values of subelement 3 and it works ok. My problem is inserting the values back into the output array in the right place. I have commented out my last attempt which failed. Sorry if I am missing the obvious here.
foreach($result as $sub)
{
//get values
$sub[3]=$sub[1]-$sub[2];
echo "<difference>".$sub[3]."<br>";//works ok
//insert values back into array
//$result[$sub[0]][3] = $sub[3];
}
print "<pre>";
print_r($result);
print "</pre>";
die();

The problem:
$result[$sub[0]][3] = $sub[3]; //= $result[1][3] = $sub[3]
$sub[0] always return 1 (according to your input array) so it's not what you're looking for.
The solution:
Use the $array as $key => $val format in your foreach loop
and then access the sub array according to the relevant key.
foreach($result as $key => $sub)
{
//get values
$result[$key][3]=$sub[1]-$sub[2];

You can use array_map too, it's more elegant:
$output = aray_map( function ($item) {
$item[] = $sub[2] - $sub[1];
return $item;
}, $arr);
Demo

Related

How to split string into an associative array which has arrays within arrays

I have the following string: names=bob;mike;sam&age=30;23;22&fav-nums=200;300;400
I was wondering if there is a function which can split this into an associative array which as arrays within it. For example
Array (
["name"] => Array
(
bob,
mike,
sam
)
["age"] => Array
(
30,
23,
22
)
["fav-nums"] => Array
(
200,
300,
400
)
)
You can user parse_str() and explode() functions to achieve this.
Steps:
1) Use parse_str() function, it will split your string into associative array.
2) Now loop over it and go for key values.
3) keys will be the required keys (names, age and fav-nums) and you want values to be array.
4) explode() the values with ; and you will get required values.
Working code:
$str = "names=bob;mike;sam&age=30;23;22&fav-nums=200;300;400";
parse_str($str, $output);
$arr = [];
if (! empty($output)) {
foreach ($output as $key => $value) {
$arr[$key] = explode(';', $value);
}
}
echo '<pre>';print_r($arr);echo '</pre>';
Output:
Array
(
[names] => Array
(
[0] => bob
[1] => mike
[2] => sam
)
[age] => Array
(
[0] => 30
[1] => 23
[2] => 22
)
[fav-nums] => Array
(
[0] => 200
[1] => 300
[2] => 400
)
)
Not sure if there is a direct method of creating the sub-arrays, but parse_str() will split the initial string by & and create the starting point, then process each element with explode() (and array_walk()) to create the sub-arrays.
$start = 'names=bob;mike;sam&age=30;23;22&fav-nums=200;300;400';
parse_str($start, $output);
array_walk($output, function ( &$data ) { $data = explode(";", $data); });
print_r($output);
which gives...
Array
(
[names] => Array
(
[0] => bob
[1] => mike
[2] => sam
)
[age] => Array
(
[0] => 30
[1] => 23
[2] => 22
)
[fav-nums] => Array
(
[0] => 200
[1] => 300
[2] => 400
)
)
You can use array_map function in order to traverse the whole array as it boost up speed of your code. Also parse_str is always use in order to read Query String and convert it in array form.
$text = 'names=bob;mike;sam&age=30;23;22&fav-nums=200;300;400';
parse_str($text, $outputArray);
$array = [];
if(!empty($outputArray)) {
$array = array_map(
function($v) {
return explode(';', $v);
}, $outputArray
);
}
echo"<pre>";
print_r($array);
The result shows
Array
(
[names] => Array
(
[0] => bob
[1] => mike
[2] => sam
)
[age] => Array
(
[0] => 30
[1] => 23
[2] => 22
)
[fav-nums] => Array
(
[0] => 200
[1] => 300
[2] => 400
)
)

running for loop on array without incremental index

I have this arbitrary multi dimensional array.
Array (
[0] => Array
(
[0] => 0
[1] => 1
[2] => 2
)
[5] => Array
(
[0] => 0
[1] => 1
[2] => 2
)
[10] => Array
(
[0] => 0
[1] => 1
[2] => 2
)
[15] => Array
(
[0] => 0
[1] => 1
[2] => 2
)
[1] => Array
(
[0] => 2
[1] => 1
[2] => 2
)
[2] => Array
(
[0] => 2
[1] => 1
[2] => 2
)
)
I wanna run a for loop to extract the data of each subarray.
But I cannot do a simple for loop because the index (0,5,10,15,1) is arbitrary.
Is there a way to run a for loop then skip the sub array if it is empty?
Thanks!
This will take $array and loop though it, echoing the keys.
You have an array in an array, you can place a foreach in a foreach:
// First we take the main array ($array) and loop though its values
foreach( $array as $main_key =>$sub_array){
echo $main_key.": <br />\n"; // echo the key, some extra html to format
// the values of the mainarray are arrays themselves, just loop again:
foreach($subarray as $sub_key =>$subvalue){
echo '- '.$subvalue."<br />\n";
}
}
There's a bit of a trap here if you foreach in a foreach:
foreach($array as $key =>$value){
foreach($value as $key=>$value){ /* ... */; }
}
This will create very weird results. The inner foreach uses the same parameter-names and will mess everything up.

Check values of sub-arrays, use key as new value in new array - PHP

I have an array, let call it $mainArray, which looks like this: -
Array
(
[1] => Array
(
)
[5] => Array
(
[0] => 10
[1] => 15
[2] => 20
[3] => 25
)
[80] => Array
(
[0] => 20
[1] => 40
[2] => 50
[3] => 60
)
[777] => Array
(
[0] => 100
[1] => 200
[2] => 300
[3] => 400
)
[666] => Array
(
[0] => 1234
[1] => 5678
[2] => 20
[3] => 9865
)
[555] => Array
(
[0] => 111
[1] => 222
[2] => 333
[3] => 444
)
)
What I want to do is create 2 new arrays: -
1) Where values are equal to the key names of $mainArray, but only those where the sub-array (if there is one) contains the value "20" somewhere in it. For example my new array (call it $arrayOne) will be [0] => 5, [1] => 80, [2] => 666.
2) Similar to above, but where there's either no sub-array or, if there is, it doesn't include "20" as a value. So that (call it $arrayTwo) would be [0] => 1, [1] => 777, [2] =>555.
I've tried loads of for each loops and even a little RecursiveIteratorIterator (whatever that is!) but can't seem to reference keys and values in the way that I need to. Any help would be much appreciated!
Will this do?:
<?php
foreach( $mainArray as $mKey => &$mVal )
{
if( in_array( 20, $mVal ) )
{
$arrayOne[] = $mKey;
}
else
{
$arrayTwo[] = $mKey;
}
}
I trust you can create a function which would check if array contains 20 as it's value or not. Let's call this function has20.
You two new arrays would then be array_filter($mainArray, 'has20') and array_filter($mainArray, function ($x) {return !has20($x);})
You can do it like this:
$newArray = array();
foreach($mainArray as $key => $subArray) {
if (in_array(20, $subArray)) {
$newArray[] = $key;
}
}

How to process second dimension of an Array based on similar first dimension value?

I am trying to write some php code to process the second dimension's value of an array based on similar values of the first dimension values.
Following is the sample output.
[0] => Array (
[0] => 1
[1] => 0.091238491238491
)
[1] => Array (
[0] => 2
[1] => 0.2221793635487
)
[2] => Array (
[0] => 2
[1] => 0.10662717512033
)
[3] => Array (
[0] => 4
[1] => 0.44354338998346
)
[4] => Array (
[0] => 6
[1] => 0.2248243559719
)
[5] => Array (
[0] => 6
[1] => 0.31764705882353
)
[6] => Array (
[0] => 6
[1] => 0.15764625384879
)
[7] => Array (
[0] => 6
[1] => 0.19160083160083
)
[8] => Array (
[0] => 12
[1] => 0.31054875069499
)
[9] => Array (
[0] => 12
[1] => 0.10915034227918
)
[10] => Array (
[0] => 15
[1] => 0.32915461266474
)
//...........goes to 46000 elements
Now what I want to do is, if the index 0 values of each array is similar then I want to add the index 1's value.
So for example, if 0 index values for 4 arrays are same , I want to add index 1 values of all 4 arrays.
If there is a unique value on 0th index, dont add it with anything, simply store index 1's value and move on.
Thanks very much.
Ghanshyam
$added = array();
foreach ($array as $item) {
if (isset($added[$item[0]])) {
$added[$item[0]] += $item[1];
} else {
$added[$item[0]] = $item[1];
}
}
$p=0;
$temp = $final_prod_ex[0][1];
for($x=0; $x<count($final_prod)-1; $x++){
if($final_prod_ex[$x][0]==$final_prod_ex[$x+1][0]){
$temp = $temp + $final_prod_ex[$x+1][1];
}
else{
$ans[$p] = $temp." ".$final_prod_ex[$x][0];
$temp = $final_prod_ex[$x+1][1];
$p++;
}
}
Finally figured it out after a lot of thinking(I'm new to programming)...Array's name is $final_prod_ex. Comment on this if I can make it better. And sorry #deceze. I could not understand your solution. I know you were trying to give the value of one array as an index to another. But what the scenario is, that value isnt like 0,1,2,3,4.... Its like 1,3,5,6,7,10. We are missing numbers in between. Maybe I didnt understand your solution. Correct me if I am wrong.
Thanks for all the help.

Changing values of all similar sub arrays in PHP

I've got the following 2D array, stored inside the array variable $my_array
Array
(
[0] => Array
(
[0] => 3
[1] => 6
[2] => 3
)
[1] => Array
(
[0] => 3
[1] => 6
[2] => 3
)
[2] => Array
(
[0] => 3
[1] => 6
[2] => 3
)
)
I wanted to decrement all the [1] sub array values by 3. Tried the following code, with no success.
$my_array[$i]['1']=($my_array[$i]['1'])-3;
print_r($my_array);
Ideas?
foreach ($my_array as &$val) {
$val[1] -= 3
}
Something like this is what you're after.
foreach($my_array as $k=>$v){
if (isset($my_array[$k][1]) && is_numeric($my_array[$k][1])){
$my_array[$k][1] -= 3;
}
}

Categories