JohnWayne
JohnWayne

Reputation: 663

Php optimize double loop (array and object)

I need optimization of loop (array) in loop (object). Below is my solution which is working, but if I try this with huge amount of data then is too slow.

Here is my array

$data = [
      ["PLZ", "Preis"],
      ["8074", "90"],
      ["8075", "90"],
      ["8076", "90"],
      ["8077", "90"],
      ["8078", "77"],
      ["1010", "77"],
      ["1020", "77"],
      ["1030", "77"],
      ["8041", "55"],
      ["8020", "89"],
    ];

Here is my object

$postal_collection = {
"1010":1,
"1020":2,
"1030":3,
"8020":1602,
"8041":1604,
"8074":1622,
"8075":1623,
"8076":1624,
"8077":1625
}

Here is working loop

$allData = [];
    foreach ($data as $key => $fields) {
      foreach ($postal_collection as $postal => $placeId) {
        if ($fields[0] == $postal) {
          $allData[$placeId] = [
            'postal' => $postal,
            'place_id' => $placeId,
            'price' => $fields[1],
          ];
        }
      }
    }

So how can I change this loop to make the same job but faster?

Upvotes: 1

Views: 69

Answers (2)

Johnny Fuery
Johnny Fuery

Reputation: 11

If $fields[0] (the first item in each $data "row") is unique you can cycle through those once and create a lookup array. The assignment of a single item from that lookup array will be fast.

Then you can cycle through $postal_collection and create your $all_data result in only one pass.

$lookup = [];    
foreach ($data as $row){
    $lookup[$row[0]] = $row[1];
}

$allData = [];
foreach ($postal_collection as $postal => $placeId) {
    if (isset($lookup[$postal]) && !isset($allData[$placeId])){
        $allData[$placeId] = [
            'postal' => $postal,
            'place_id' => $placeId,
            'price' => $lookup[$postal]
         ];
     }
}

Upvotes: 0

Syscall
Syscall

Reputation: 19780

You could avoid one foreach by using keys of $postal_collection:

$allData = [];
foreach ($data as $key => $fields) {
    $id = $fields[0] ;
    // check if the key exists in $postal_collection:
    if (!isset($postal_collection[$id])) continue ;
    // get the value
    $cp = $postal_collection[$id];
    // add to $allData
    $allData[$cp] = [
        'postal' => $id,
        'place_id' => $cp,
        'price' => $fields[1],
      ];
}
print_r($allData);

Outputs:

Array
(
    [1622] => Array
        (
            [postal] => 8074
            [place_id] => 1622
            [price] => 90
        )

    [1623] => Array
        (
            [postal] => 8075
            [place_id] => 1623
            [price] => 90
        )

    [1624] => Array
        (
            [postal] => 8076
            [place_id] => 1624
            [price] => 90
        )

    [1625] => Array
        (
            [postal] => 8077
            [place_id] => 1625
            [price] => 90
        )

    [1] => Array
        (
            [postal] => 1010
            [place_id] => 1
            [price] => 77
        )

    [2] => Array
        (
            [postal] => 1020
            [place_id] => 2
            [price] => 77
        )

    [3] => Array
        (
            [postal] => 1030
            [place_id] => 3
            [price] => 77
        )

    [1604] => Array
        (
            [postal] => 8041
            [place_id] => 1604
            [price] => 55
        )

    [1602] => Array
        (
            [postal] => 8020
            [place_id] => 1602
            [price] => 89
        )

)

Upvotes: 3

Related Questions