4

I'm trying to find a simpler way to create new arrays from existing arrays and values. There are two routines I'd like to optimize that are similar in construction. The form of the first one is:

$i = 0;
$new_array = array();
foreach ($my_array as $value) {                 
    $new_array[$i][0] = $constant;  // defined previously and unchanging
    $new_array[$i][1] = $value;     // different for each index of $my_array
    $i++;
}

The form of the second one has not one but two different values per constant; notice that $value comes before $key in the indexing:

$i = 0;
$new_array = array();
foreach ($my_array as $key => $value) {                 
    $new_array[$i][0] = $constant;  // defined previously and unchanging
    $new_array[$i][1] = $value;     // different for each index of $my_array
    $new_array[$i][2] = $key;   // different for each index of $my_array
    $i++;
}

Is there a way to optimize these procedures with shorter and more efficient routines using the array operators of PHP? (There are many, of course, and I can't find one that seems to fit the bill.)

Tom
  • 1,836
  • 4
  • 16
  • 30

4 Answers4

1

I believe a combination of Wouter Thielen's suggestions regarding the other solutions actually holds the best answer for me.

For the first case I provided:

$new_array = array();
// $my_array is numeric, so $key will be index count:
foreach ($my_array as $key => $value) { 
    $new_array[$key] = array($constant, $value);
};

For the second case I provided:

// $my_array is associative, so $key will initially be a text index (or similar):
$new_array = array();
foreach ($my_array as $key => $value) { 
    $new_array[$key] = array($constant, $value, $key);
};
// This converts the indexes to consecutive integers starting with 0:
$new_array = array_values($new_array);
Tom
  • 1,836
  • 4
  • 16
  • 30
  • Actually, Tom, in the title you were asking for a solution "without using foreach construction". In that case, my answer would be more correct, but still not optimized though. – Wouter Thielen Aug 30 '15 at 05:31
0

it is shorter, when you use the array-key instead of the $i-counter

$new_array = array();
foreach ($my_array as $key => $value) {                 
    $new_array[$key][0] = $constant;  // defined previously and unchanging
    $new_array[$key][1] = $value;     // different for each index of $my_array
}
Bernhard
  • 1,852
  • 11
  • 19
0

Use array_map:

$new_array = array_map(function($v) use ($constant) {
    return array($constant, $v);
}, $my_array);

If you want to use the keys too, for your second case:

$new_array = array_map(function($k, $v) use ($constant) {
    return array($constant, $v, $k);
}, array_keys($my_array), $my_array);

Assuming the $constant variable is defined in the caller's scope, you'll need to use use ($constant) to pass it into the function's scope.

array_walk is similar, but modifies the array you pass to it, so if you want to update $my_array itself, use array_walk. Your second case then becomes this:

array_walk($my_array, function(&$val, $key) use($constant) {
    $val = array($constant, $val, $key);
});

In both examples above for the second case, you'll end up with an associative array (i.e. with the keys still being the keys for the array). If you want to convert this into a numerically indexed array, use array_values:

$numerically_indexed = array_values($associative);
Wouter Thielen
  • 1,016
  • 9
  • 21
  • I like your suggestion to use array_values() and your suggestion to the other post...my adoption below. – Tom Aug 29 '15 at 14:28
  • According to http://stackoverflow.com/questions/18144782/performance-of-foreach-array-map-with-lambda-and-array-map-with-static-function, the `foreach` is still faster, so yes, your adoption would be better performance-wise. – Wouter Thielen Aug 29 '15 at 15:21
0

I asked a question similar to this a few days ago, check it out:

PHP - Fastest way to convert a 2d array into a 3d array that is grouped by a specific value

I think that you have an optimal way when it comes to dealing with large amount of data. For smaller amounts there is a better way as was suggested by the benchmarks in my question.

I think too that readability and understanding the code can also be an issue here and I find that things that you can understand are worth more later on than ideas that you do not really grasp as it generally takes a long time to understand them again as it can be quite confusing while debugging issues.

I would suggest, you take a look at the differences between JSON encoded arrays and serialised arrays as there can be major performance differences when working with the two. It seems that as it is now JSON encoded arrays are a more optimised format (faster) for holding and working with data however this will likely change with PHP 7. It would be useful to note that they are also more portable.

Further Reading:

Preferred method to store PHP arrays (json_encode vs serialize)

http://techblog.procurios.nl/k/n618/news/view/34972/14863/cache-a-large-array-json-serialize-or-var_export.html

Community
  • 1
  • 1
Craig van Tonder
  • 7,497
  • 18
  • 64
  • 109