Modify array values in foreach loop
Solution 1
There are 2 ways of doing this
foreach($questions as $key => $question){
$questions[$key]['answers'] = $answers_model->get_answers_by_question_id($question['question_id']);
}
This way you save the key, so you can update it again in the main $questions
variable
or
foreach($questions as &$question){
Adding the &
will keep the $questions
updated. But I would say the first one is recommended even though this is shorter (see comment by Paystey)
Per the PHP foreach
documentation:
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.
Solution 2
Surely using array_map
and if using a container implementing ArrayAccess
to derive objects is just a smarter, semantic way to go about this?
Array map semantics are similar across most languages and implementations that I've seen. It's designed to return a modified array based upon input array element (high level ignoring language compile/runtime type preference); a loop is meant to perform more logic.
For retrieving objects by ID / PK, depending upon if you are using SQL or not (it seems suggested), I'd use a filter to ensure I get an array of valid PK's, then implode with comma and place into an SQL IN()
clause to return the result-set. It makes one call instead of several via SQL, optimising a bit of the call->wait
cycle. Most importantly my code would read well to someone from any language with a degree of competence and we don't run into mutability problems.
<?php
$arr = [0,1,2,3,4];
$arr2 = array_map(function($value) { return is_int($value) ? $value*2 : $value; }, $arr);
var_dump($arr);
var_dump($arr2);
vs
<?php
$arr = [0,1,2,3,4];
foreach($arr as $i => $item) {
$arr[$i] = is_int($item) ? $item * 2 : $item;
}
var_dump($arr);
If you know what you are doing will never have mutability problems (bearing in mind if you intend upon overwriting $arr
you could always $arr = array_map
and be explicit.
Garbit
Bio I'm a UX Researcher and Software Engineer at Samsung AI Center - Cambridge. I explore Human-Centric AI through the design of wellbeing technologies that promote a deeper understanding of ourselves using computer vision, ubiquitous sensing, and personal data. I am an experienced full-stack developer with a keen interest in designing compelling user experiences and developing innovative products for both mobile and web. I lead products from design concepts to full implementation working alongside engineers, designers, and researchers to realise next generation technologies. I have a background in both Software Engineering and UX Research and thoroughly enjoy designing and developing civic technology that empowers and connects people through web and mobile platforms. Find our more on my portfolio site http://andygarbett.co.uk Dev Projects https://App-Movement.com a platform for communities to commission and automatically generate their own mobile apps around the real world issues that they face. http://Feed-Finder.co.uk, a mobile app that allows breastfeeding mothers to rate and review suitable breastfeeding locations. http://irismsg.io, a distributed SMS donation platform that enables individuals to donate SMS credit to solidarity groups in Greece. http://Sleepful.me, a social network to deliver cognitive behavioural therapy to those with insomnia and severe sleep disorders. http://Fearsquare.com, a Foursquare & UK Police data mashup that creates a personal crime exposure history from your Foursquare checkin data. http://collectionsdivetwmuseums.org.uk, a novel discovery interface for online heritage collections created in partnership with Tyne and Wear Archives and Museums and Microsoft Research Cambridge.
Updated on March 03, 2021Comments
-
Garbit about 3 years
I was wondering if it is possible to edit the current object that's being handled within a
foreach
loopI'm working with an array of objects
$questions
and I want to go through and look for the answers associated with that question object in my db. So for each question go fetch the answer objects and update the current$question
inside myforeach
loop so I can output/process elsewhere.foreach($questions as $question){ $question['answers'] = $answers_model->get_answers_by_question_id($question['question_id']); }
-
Garbit about 12 yearsNice! so the & sign will pass by reference? is that the correct terminology?
-
jemcmorrow about 12 yearsyou are missing part with passing entire
$question
variable into get_answers_by_question_id() -
Rene Pot about 12 years@ArtjomKurapov what do you mean? What part
-
Paystey about 12 yearsReferences in
foreach
is really not recommended, the way theforeach
passes around the value part of the loop results in unpredicatble behaviour. It may be longer but you're far safer using method 1 here. -
jemcmorrow about 12 years@Topener well he needs $question to be updated inside
get_answers_by_question_id
.. and you are just passing its id -
Rene Pot about 12 years@ArtjomKurapov I think either you or me misunderstood the question. Thats not what I see he asked
-
jemcmorrow about 12 years@Topener right.. I thought
get_answers_by_question_id
does more than just fetch data from DB and actually changes$question
inside too -
Garbit about 12 yearsI've found that both methods above work however considering what @Paystey has said I've used the Key Value pair type loop instead of the by reference, it seems messy having the use unset($question) after the loop
-
Hippyjim over 10 yearsI just spent a perplexed hour debugging an issue caused by using a reference in a foreach. I re-used the same variable name for a second foreach call - as I'd passed the first by reference, it kept modifying the last item in the array! Using an explicit index wouldn't have had this problem.
-
Nico over 8 years@Paystey can you cite your sources or give a detailed explaination ?
-
Kalzem about 8 yearsWhy would manipulating references be unsafe? Is C/C++ where you have to manipulate references everywhere unsafe? It's up to you to make it safe or not, not the language.
-
Sz. about 7 years@BabyAzerty: Paystey didn't say references "in general", but in
foreach
, regarding horror like this: stackoverflow.com/questions/3307409/… (@Nico, FYI, too.) -
benjaminhull over 5 yearsMuch more intuitive than doing a foreach - this is exactly what this function is designed for.
-
COil over 2 yearsExcept that you don't have access to the key.