1

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?

4
  • 2
    That "object" does not look like PHP code Commented Mar 16, 2018 at 8:54
  • Since your work with array, try somehting with php array_map maybe using a callback that return you the expecting result ? Commented Mar 16, 2018 at 8:54
  • 1
    @NicoHaase that is output from response json_encode($response) just that you see how it look like (structure) Commented Mar 16, 2018 at 8:55
  • 1
    Tip: you can directly access array indices, you don't have to loop every array entry: $postal_collection[$fields[0]]. Commented Mar 16, 2018 at 8:55

2 Answers 2

3

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
        )

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

2 Comments

With this solution I have to convert $postal_collections to array (you can not reach to object using $postal_collection[$id]) - but however it is faster than 2 foreach
@JohnWayne Right. You could use json_decode($data, true) to convert to an associative array.
0

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]
         ];
     }
}

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.