Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

This works, but do I have to make a new array, result, or is there a way to just insert the field I need into each $key of the received parameter $data?

Won't this way take up more memory needlessly?

function add_tax($data){
            $result = [];
            foreach($data as $product => $details) {
                $details['tax'] = 0;
                $result[$product] = $details;
                } 
            return $result;
          }
share|improve this question
add comment

2 Answers 2

up vote 3 down vote accepted

You could try something along these lines:

function add_tax($data){
        foreach($data as $product => $details) {
            $data[$product]['tax'] = 0;
        }
        return $data;
}

EDIT 1:

After a bit more researching on foreach I have come up with the following alternative:

function add_tax(&$data) {
    foreach($data as &$details)
        $details['tax'] = 0;
}

In reference to Alex L: I apologize, the original answer was rushed. The first snippet was simply a way of answering the question, that yes, it is possible to iterate through $data without generating a new variable. Also, to MikeiLL, yes, that would be a waste of memory. This second snippet passes both variables by reference, which does not require any excess usage of memory. It is the most optimal format of this process.

NOTE: The unset in the function is not exactly necessary, but as your question referenced memory usage, unset breaks the reference and releases that memory.

EDIT 2:

Due to very strong backing in the comments, I've removed the call to unset (truth be told I'd never use it myself, but wanted to reference it's usage within the function)

share|improve this answer
    
Ya know what would make your answer even better? If I knew why you changed what you did, and how that improves the original code! –  Alex L Jul 17 at 17:36
1  
You don't need the unset since $details goes out of scope immediately and is not reused. –  David Harkness Jul 17 at 18:52
2  
unset() does just what it's name says - unset a variable. It does not force immediate memory freeing. PHP's garbage collector will do it when it see fits as unset() just decrements the refcount by one. If, and only if, the refcount reaches zero, then PHP knows no more symbols point to the zval, and will free the refcount automatically. –  jsanc623 Jul 17 at 19:34
1  
Nope, because $data is passed as a reference, there's no need to return it. –  Travis Weston Jul 17 at 19:38
1  
@MikeiLL This is why I tend to favor functions without side-effects that return a copy of the data modified appropriately. Both have their uses, however. :) –  David Harkness Jul 17 at 22:23
show 7 more comments

PHP provides quite a few handy array-manipulation functions. This is a case for array_map which passes each value to a callback and assigns it to the same key in a new array.

function add_tax(array $data) {
    return array_map(function ($details) {
        $details['tax'] = 0;
        return $details;
    }, $data);
}

This version won't modify the original $data array passed to add_tax.

How does this differ from writing your own loop using foreach? Mostly in style. You'll pay a minor performance penalty switching between system and user space (once for each call to the callback), but you won't notice this unless $data is huge.

It looks much nicer when the callback returns an immediate expression instead of using one statement to modify and another to return. You can do this here using array_merge. In fact, this also allows you to refactor add_tax into a generic helper function.

function extend_arrays(array $arrays, array $additions) {
    return array_map(function ($array) use ($additions) {
        return array_merge($array, $additions);
    }, $arrays);
}

function add_tax($data) {
    return extend_arrays($data, array('tax' => 0));
}

function add_tax_and_shipping($data) {
    return extend_arrays($data, array('tax' => 0, 'shipping' => 0));
}
share|improve this answer
3  
I'm actually extremely fond of this question now. One of the things I love about programming is how you can solve the same problem infinite numbers of ways. My example was an attempt at removing as much as I could, and giving the simplest version of a solution as I could. This is an example of a more robust, expandable solution. –  Travis Weston Jul 17 at 19:40
    
This is beautiful. Learned about array maps in Eloquent Javascript. For some reason I'm getting Undefined variable: additions, though... –  MikeiLL Jul 17 at 20:14
1  
@MikeiLL Fixed, thanks! I was missing the use clause to give the callback access to $additions. Probably too much JavaScript lately which doesn't require such nonsense. –  David Harkness Jul 17 at 22:22
    
Ahhh. I spent about an hour trying to make the useless version work. :) Thank you, professor. –  MikeiLL Jul 17 at 23:19
    
So in this case, would it have to be an anonymous function to work, and is the parameter referenced by use always pulled from an outer function? –  MikeiLL Jul 18 at 0:42
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.