Question

So here's what I'm doing, I've got one array with customers and one with orders and so I'm making a new array from the data in these two... Here's some code:

Customer Array:

Array
(
    [0] => Array
        (
            [customerid] => 1234
            [name] => John Doe
            [email] => john@doe.com
        )

    [1] => Array
        (
            [customerid] => 4321
            [name] => Jane Smith
            [email] => jane@smith.com
        )

    (etc...)
)

Orders array:

Array
(
    [0] => Array
        (
            [customerid] => 1234
            [amount] => 100.00
            [date] => 2012-05-11
        )

    [1] => Array
        (
            [customerid] => 4321
            [amount] => 200.00
            [date] => 2012-03-01
        )

    [2] => Array
        (
            [customerid] => 4321
            [amount] => 500.00
            [date] => 2012-02-22
        )

    (etc...)
)

Final array:

Array
(
    [1234] => Array
        (
            [name] => John Doe
            [email] => john@doe.com
            [orders] => Array
                (
                    [0] => Array
                        (
                            [amount] => 100.00
                            [date] => 2012-05-11
                        )

                )

        )

    [4321] => Array
        (
            [name] => Jane Smith
            [email] => jane@smith.com
            [orders] => Array
                (
                    [0] => Array
                        (
                            [amount] => 200.00
                            [date] => 2012-03-01
                        )
                    [1] => Array
                        (
                            [amount] => 500.00
                            [date] => 2012-02-22
                        )

                )

        )

    (etc...)
)

So... This is the PHP code that I thought of:

$customers = array(blah...); # See above...
$orders    = array(blah...); # See above...
$new_array = array();

foreach ($customers as $c) {
  $new_array[$c['customerid']] = array(
    'name'   => $c['name'],
    'email'  => $c['email'],
    'orders' => array()
  );
}

foreach ($orders as $o) {
  $new_array[$o['customerid']]['orders'][] = array(
    'amount' => $o['amount'],
    'date'   => $o['date']
  );
}

Finally, we're at the topic of this post! Do any of you have any tips for optimizing this in any way? Or was right on track to begin with... That'd be nice too though... Anyhow, any tips are appreciated even if I choose to not follow them... Thanks in advance...

Was it helpful?

Solution

As I said in the comment, it looks fine. One thing you can do to shorten your code though is not to mention all the fields again when creating the new array, which can save you quite a bit of typing if you have a lot fields in the end.

For example instead of:

foreach ($customers as $c) {
  $new_array[$c['customerid']] = array(
    'name'   => $c['name'],
    'email'  => $c['email'],
    'orders' => array()
  );
}

You can just do:

foreach ($customers as $c) {
  $new_array[$c['customerid']] = $c;
  $new_array[$c['customerid']]['orders'] = array();
}

There's usually no reason to prematurely optimize code, just make it work and optimize it if required (of course having a good basis knowledge of what is good and what is bad will help you write good quality code in the first place).

EDIT

If you are genuinely just curious about how to make it faster, there are ways to do it. For example if you don't need to care about the original two arrays after you've created the new array, you can change your code around a bit to remove all unnecessary array copies. PHP has an internal reference counting mechanism, where a copy of an array is not made upon assignment, but only when you actually modify the array later on (this is called copy-on-write). For example:

foreach ($customers as $c) {
  $new_array[$c['customerid']] = $c; // $c is not yet actually copied here, PHP just creates an internal reference to $c
  $new_array[$c['customerid']]['orders'] = array(); // this is what copies the underlying array, as it is now modified
}

Keeping that in mind, if you don't care that the original $customers and $orders arrays stay untouched after generating $new_array, you can simply modify the original arrays to prevent unnecessary copying:

// iterate through the array by reference
foreach ($customers as &$c) {
  $c['orders'] = array(); // modifies the original $customers array
  $new_array[$c['customerid']] = $c;
}

// clean up the reference, to prevent accidents later on
unset($c);

// there's no need to use a reference here, as PHP's internal refcounting mechanism will kick in
foreach ($orders as $o) {
  $new_array[$o['customerid']]['orders'][] = $o;
}

// finally if you don't need the original arrays anymore, clean up after them
// this also means that modifying $new_orders afterwards will not create a copy
// of anything, as $new_orders is the only array keeping internal references
// to the customers and orders
unset($customers, $orders);

But again I re-iterate, there's really no need to prematurely optimize like this. Prefer clean, readable code, and only optimize if it's necessary.

OTHER TIPS

Looks about right to me, though I'm no PHP expert. Can't optimize much more than that. Also, I would be careful about premature optimization. Get your code working completely before you go around trying to speed things up-- it'll save you a world of pain in the future.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top