Adding to a multidimensional associative array (in PHP) - php

I'm returning an associative array via PDO that has the structure:
Array
(
[0] => Array
(
[pesttopicID] => 42
[sPestName] => CMSM Trap Surveying and Pest Management
[quizID] => 609
[bTier1] => 1
[sDesc] => Workshop assessment
)
[1] => Array
(
[pesttopicID] => 34
[sPestName] => Trap Surveyor
[quizID] => 451
[bTier1] => 1
[sDesc] => Competency for CM OAP
)
)
I want to add a key-value pair to the "inner" array, but all my attempts of trying to use posted solutions to the generic issue of adding to an associative array...
:
$results = $statement->fetchAll(PDO::FETCH_ASSOC);
$newkey='myNewKey';
$newval='myNewValue';
foreach($results as $row){
$results[][$newkey] = $newval;
foreach ($row as $key=>$value){
... some reporting stuff
}
}
...result in the pair being added to the "outer" array e.g.
Array
(
[0] => Array <---- I want the new pair in this "inner" array
(
[pesttopicID] => 42
[sPestName] => CMSM Trap Surveying and Pest Management
[quizID] => 609
[bTier1] => 1
[sDesc] => Workshop assessment
)
[1] => Array <---- I want the new pair in this "inner" array
(
[pesttopicID] => 34
[sPestName] => Trap Surveyor
[quizID] => 451
[bTier1] => 1
[sDesc] => Competency for CM OAP
)
[2] => Array
(
[myNewKey] => myNewValue
)
)
Is this possible?
Thanks/Tom

You have to it like below:-
$newkey='myNewKey';
$newval='myNewValue';
foreach($results as &$row){ //use reference variable
$row[$newkey] = $newval;// remove the second foreach if not necessary
//if second foreach is necessary then add it no problem
}
Output:-https://eval.in/856983
Or you can do like this also:-
$newkey='myNewKey';
$newval='myNewValue';
foreach($results as $key=>$row){ //use key now
$results[$key][$newkey] = $newval;// remove the second foreach if not necessary
//if second foreach is necessary then add it no problem
}
Output:-https://eval.in/856987

Related

Add element to PHP associative array in loop

I've looked but can't find an answer for my specific use case. I want to add an element to a multidimensional array while looping through it. What I have before the loop:
Array
(
[fname] => Monty
[lname] => Python
[phone] => 555 555 1212
[email] => a#b.com
[modelList] => Array
(
[0] => Array
(
[id] => 1
[modelName] => X-Wing
[remarks] =>
[htmlRemarks] =>
[category] => Vehicles
[catID] => 178
[attachedToBase] => 1
[oversized] => 0
)
)
)
In code, I'm looping through the [modelList] array and after doing some database operations what I want to do is append new elements to each model array - in the case below, the [dbID]:
Array
(
[fname] => Monty
[lname] => Python
[phone] => 555 555 1212
[email] => a#b.com
[modelList] => Array
(
[0] => Array
(
[id] => 1
[modelName] => X-Wing
[remarks] =>
[htmlRemarks] =>
[category] => Vehicles
[catID] => 178
[attachedToBase] => 1
[oversized] => 0
[dbID] => 907
)
)
)
All inputs are from a form POST, and in my php handler:
// Loop thru model entries
$modelList = json_decode($_POST["modelList"], TRUE);
foreach($modelList as $model) {
(do some work)
// Add the new element
array_push($model['dbID'], $newID);
}
But this throws an error:
PHP Warning: array_push() expects parameter 1 to be array, null given
How can I add the new element to the sub-array?
array_push
Push one or more elements onto the end of array
You can't add a key value item to an array using array_push.
Use this instead :
foreach ($modelList as $key => $model){
$modelList[$key]['dbID'] = $newID;
}
Based on your snippet with the loop are you trying to actually update the dbID?
If so, you should change the logic to:
foreach ($modelList as $key => $model) {
(do some work)
$modelList[$key]['dbID'] = $newID;
}
Why:
you cannot change contents of the array you are looping over (unless accessed by reference)
in your example code $model['dbID'] is number 907 which is not an array, hence the error message
Found it - I needed to use a reference to $model in order to update it
// Loop thru model entries
$modelList = json_decode($_POST["modelList"], TRUE);
foreach($modelList as &$model) {
(do some work)
// Add the new element
$model['dbID'] = $newID;
}
unset($model);

PHP array not setting custom key in a foreach loop

I'm looping through a database object returned by MySQL in CodeIgniter 2.x (PHP). The array $gifts has been declared outside the loop before it begins.
There is an inner loop and an outer loop. The outer loop generates the second array example below. The inner loop generates the problem array.
In LINE 2, $i['gifts'][$row->id_gift] correctly setting the keys with the desired id $row->id_gift. In LINE 1, it is not. The array key is being assigned numerically in order from 0-n as if it were being set with $gifts[][$sd] = $row->$sd.
Any thoughts on why?
$query = $this->db->get();
if ($query->num_rows() > 0)
{
foreach ($query->result() as $row)
{
foreach ($select_details as $sd)
{
$gifts[$row->id_gift][$sd] = $row->$sd; // LINE 1
$i['gifts'][$row->id_gift] = array('merchant_rank'=>$i['merchant_rank'],'rank'=>$row->rank); // LINE 2
}
}
}
$select_details = array('id_gift','id_group','rank');
Array (LINE 1) output sample:
Array (
[0] =>
Array (
[id_gift] => 392
[id_group] => 244
[rank] => 1
)
[1] => Array (
[id_gift] => 287
[id_group] => 239
[rank] => 1
)
[2] => Array (
[id_gift] => 264
[id_group] => 4
[rank] => 1)
)
Array (LINE 2) output sample (note the correct keys in the gifts array):
Array (
[0] => Array
(
[id] => 49
[id_group] => 49
[id_merchants] => 116
[gifts] => Array
(
[392] => Array
(
[merchant_rank] => 1
[rank] => 1
)
[287] => Array
(
[merchant_rank] => 1
[rank] => 2
)
[264] => Array
(
[merchant_rank] => 1
[rank] => 3
)
)
)
)
RESOLVED. See my answer below if you're curious. Thanks for your help #Spartan and #DontPanic.
Okay, I figured out the problem. And the more experienced programmers among you might not be all that surprised.
Later in the script I'm using a multidimensional array sort that's destroying the keys. I'm sure there's a way to prevent that, but that's not pertinent here.
usort($gifts, function($a, $b) {
return $a['rank'] - $b['rank'];
});

PHP - Incrementally add array value

Basically I have this from a query:
Array
(
[0] => Array
(
[period] => 2014-03
[val] => 2.19
[type] => TypeX
),
[1] => Array
(
[period] => 2014-03
[val] => 2.02
[type] => TypeY
)
)
Using a foreach loop to populate another array we will call DATA, I want the to get the following:
Array
(
[TypeX] => Array
(
[2014-03] => 2.19
)
[TypeY] => Array
(
[2014-03] => 2.02
)
)
The whole thing is looped because my query needs to run each time for a different period. Current exemple, second loop would run for 2014-04. My problem is when I arrive for the 2nd time at my DATA array, I want this:
Array
(
[TypeX] => Array
(
[2014-03] => 2.19
[2014-04] => 1.10
)
[TypeY] => Array
(
[2014-03] => 2.02
[2014-04] => 4.74
)
)
My code is roughly like this:
$data = array();
foreach($graph_period as $period){
$rows = Queryfunction($period,$WHERE,$byType);
foreach($rows as $row){
$data[$row['type']] = array($row['period']=>$row['val']);
}
}
Because the key of the first level (TypeX, TypeY) are the same, the valei is overwritten. How am I to append the array instead of overwriting ?
foreach($rows as $row){
$data[$row['type']][$row['period']] = $row['val']);
}
You only need to change a tiny bit. Inside the foreach where you set the value:
if( !isset($date[$row['type']]) ) {
$data[$row['type']] = array();
}
$data[$row['type']][$row['period']] = $row['val'];
So, you create the array only if it does not exist.

Why I'm not able to add new key value pair in an associative array?

I've a large associative array titled $data. For your understanding I'm printing below one element from it.
Array
(
[0] => Array
(
[id] => 92
[zip_code] => 07080
[phone_no] => 7327630062
[amount] =>
[currency] => $
[product_details] => Array
(
)
)
[1] => Array
(
[id] => 93
[zip_code] => 07081
[phone_no] => 7327630063
[amount] => 20
[currency] => $
[product_details] => Array
(
)
)
)
Now I want to create a new key-value pair in every element of the above associative array titled $data. For it I wrote following logic but it's not creating a new key-value pair. Can someone please help me in this regard?
foreach($data as $key => $value) {
if(!empty($value['amount'])) {
$value['final_amount'] = $value['amount'] - 2;
} else
$value['final_amount'] = '';
}
From the manual of foreach:
In order to be able to directly modify array elements within the loop
precede $value with &. In that case the value will be assigned by
reference.
foreach($data as $key => &$value)
In the foreach loop, pass the $value by reference by adding an ampersand & before the variable name:
foreach($data as $key => &$value)
This will allow the loop to modify the original $data instead of modifying a copy of it.

Merge arrays together based on different values

I am having trouble thinking of the logic with the following problem:
I have the following array (has been snipped, as its much larger)
Array
(
[0] => Array
(
[code] => LAD001
[whqc] => GEN
[stocktag] => NONE
[qty] => 54
)
[1] => Array
(
[code] => LAD001
[whqc] => GEN
[stocktag] => NONE
[qty] => 6
)
[2] => Array
(
[code] => LAD004
[whqc] => HOLD
[stocktag] => NONE
[qty] => 6
)
)
I basically need to comebine all the keys in this array so that where the code, whqc and stocktag are the same, add the qty values together. With the example below, I need to end up with this:
Array
(
[0] => Array
(
[code] => LAD001
[whqc] => GEN
[stocktag] => NONE
[qty] => 60
)
[1] => Array
(
[code] => LAD004
[whqc] => HOLD
[stocktag] => NONE
[qty] => 6
)
)
As the first and second keys of the array had the same code, whqc and stocktag, the qty's have been added together into the one key.
Any ideas?
I would suggest combining the group values in to a hash, storing the full array under the hash as a key and if you have a duplicate, add the quantity, then do array_values() to pull the results.
$aggregated = array();
foreach ($records as $cRec) {
// The separator | has been used, if that appears in the tags, change it
$cKey = md5($cRec['code'] . '|' . $cRec['whqc'] . '|' . $cRec['stocktag']);
if (array_key_exists($cKey, $aggregated)) {
$aggregated[$cKey]['qty'] += $cRec['qty'];
} else {
$aggregated[$cKey] = $cRec;
}
}
// Reset the keys to numerics
$aggregated = array_values($aggregated);
I would try something like:
$output = array();
foreach($array as $details){
//make distinct key
$key = $details['code'].'_'.$details['whqc'];
if(!isset($output[$key])){
$output[$key] = $details;
}else{
$output[$key]['qty'] += $details['qty'];
$output[$key]['stocktag'] = $details['stocktag'];
}
}
$output = array_values($output);
print_r($output);
update: Orbling was first ;-)

Categories