4

I have an array that looks something like that

array(
     [0] => array(
               'id' => 1,
               'title' => 'title 1',
     ),
     [1] => array(
               'id' => 10,
               'title' => 'title 10',
     ),
     [2] => array(
               'id' => 11,
               'title' => 'title 11',
     ),
     [...]
);

I want to add an element to all the sub array. It's the same element i'm adding. so the new array will look like :

array(
     [0] => array(
               'id' => 1,
               'title' => 'title 1',
               'type'  => 'bag',
     ),
     [1] => array(
               'id' => 10,
               'title' => 'title 10',
               'type'  => 'bag',
     ),
     [2] => array(
               'id' => 11,
               'title' => 'title 11',
               'type'  => 'bag',
     ),
     [...]
);

Is there a way to do it without iterating on the the first array? It's gonna be a big array. I'm looking for the fastest way to do it.

5
  • 4
    Well, internally iteration is going to happen even if you used something like array_map() Commented Dec 8, 2011 at 19:08
  • 1
    Or by without iterating do you mean you just don't want a multiline foreach loop? Commented Dec 8, 2011 at 19:09
  • It's an array from with results from a db (up to a few hundreds). I assume a foreach loop will be slow. hence without iterating. I meant a fast way. Commented Dec 8, 2011 at 19:19
  • 2
    @chaft: You assume. Have you tested it? An array with a few hundred (or thousand, for that matter) elements in it will be iterated in a few milliseconds. And even array_walk() iterates the array internally, there is no magic involved. ;) Commented Dec 8, 2011 at 19:25
  • stackoverflow.com/q/4364997/2943403 Commented Sep 10, 2020 at 11:35

3 Answers 3

7

Whatever speed one might hope to gain by using array_walk, is lost with function overhead. Since you stated in your comments that the array is a result of a db query, you can simply include the bag value in your result set by adding SELECT 'bag' AS 'type' to your SQL statement.

$start = 0; $end = 0;

$orig = array(
    array('id' => 1,  'title' => 'title 1'),
    array('id' => 10, 'title' => 'title 10'),
    array('id' => 11, 'title' => 'title 11')
);

// A
$start = microtime(true);
for ($a=0; $a<1000; $a++) {
    $els1 = $orig;
    array_walk($els1, function(&$val, $key){$val['type'] = 'bag';});
}
$end = microtime(true);
echo 'A: ', $end - $start,  "<br />\n";

// B
$start = microtime(true);
for ($b=0; $b<1000; $b++) {
    $els2 = $orig;
    foreach ($els2 as &$el) {
        $el['type'] = 'bag';
    }
    unset($el);
}
$end = microtime(true);
echo 'B: ', $end - $start,  "<br />\n";

/* output:

A: 0.0076138973236084
B: 0.0047528743743896

A: 0.0075309276580811
B: 0.0045361518859863

A: 0.0075531005859375
B: 0.062379837036133

A: 0.0075340270996094
B: 0.0044951438903809

A: 0.0074868202209473
B: 0.0044751167297363

A: 0.0076088905334473
B: 0.0048189163208008

*/
Sign up to request clarification or add additional context in comments.

Comments

3

Logically, no, there isn't any way to do it without iterating the parent array. But you can make it less painful by using array_walk(). EDIT: benchmark shows array_walk (or array-_map) is slower by a third, so I take this back.

6 Comments

How to make it less painful with array_walk in php < 5.3?
@Jonathan Kuhn: so you think that creating additional function less painful than to traverse it by foreach with 1 line?
@zerkms yes. array_walk iterates internally, without opcode processing overhead. Try this and see how long it runs: foreach(range(1,1000000) as $i) {}; (yes, empty loop taking XX seconds. Rewrite that to for($i = 0; $i < 1000000; $i++) {} and it will take even more).
@NoICE: dude, you told about array_walk() as less painful solution. So I asked you how in php < 5.3 it can be less painful. Where for vs foreach came from?! Have you seen the answer above yours: stackoverflow.com/a/8436642/251311 ??? iterates internally -- yes, it does iterate internally, BUT it calls a function. Function call is much more expensive than just assignment
@zerkms less painful [than iterating it manually -> and what keywords we use for iterating? for and foreach.]. Also, by "less painful" I ment "less painful for the server, for performance hit". Function call in php is fast and in this case it is done internally, too (though I don't have that confirmed, maybe foreach with reference assignment is faster for this purpose. As I think about it it should. Wait a minute, I will benchmark it. ... Oh I've just noticed that someone already did that, so you are right, foreach is faster for this purpose.. even if it is just by 3 miliseconds :D ).
|
3

From a simple/clean code point of view this solution suits:

$orig = array(
array('id' => 1,  'title' => 'title 1'),
array('id' => 10, 'title' => 'title 10'),
array('id' => 11, 'title' => 'title 11'));

foreach($orig as $key => $value)
{
    $value['type'] = 'bag';
    $orig[$key] = $value;   
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.