Saiyan Prince
Saiyan Prince

Reputation: 4020

Laravel swap the position in collection - multidimensional array

Following is the array in the collection:

array:1 [▼
  "online" => array:2 [▼
    "IS-003" => array:19 [▼
      "product" => Product {#831 ▶}
      "quantity" => 1
      "payment-option" => "online"
    ]
    "HA4" => array:19 [▼
      "product" => Product {#822 ▶}
      "quantity" => 1
      "payment-option" => "online"
    ]
  ]
]

Whenever a user changes the payment-option, accordingly the above array should change.

For instance, if HA4['payment-option'] is changed from online to cod, then there should be 2 arrays in parent array. Following is the array that I want as result.

array:2 [▼
  "online" => array:1 [▼
    "IS-003" => array:19 [▼
      "product" => Product {#831 ▶}
      "quantity" => 1
      "payment-option" => "online"
    ]
  ]
  "cod" => array:1 [▼
    "HA4" => array:19 [▼
      "product" => Product {#822 ▶}
      "quantity" => 1
      "payment-option" => "cod"
    ]
  ]
]

The thing that I have tried so far but couldn't get the desired result:

$paymentOptionCart = collect();

foreach ($cart as $paymentType => &$details) {
    foreach ($details as $c => $p) {
        if ($c == $code) {
            $details[$c]['payment-option'] = $request->option;
            $paymentOptionCart->put($paymentType, $details);

            unset($details[$c]);
        }
    }
}

On executing the above code, nothing happens except the payment-option is updated to cod.

I know I am making a silly mistake somewhere, but I am unable to locate where and how.

Can anybody help me out?

Upvotes: 1

Views: 2018

Answers (2)

Martin Zeitler
Martin Zeitler

Reputation: 76669

unset($details[$c]) seems to be the problem... this punches out the element at index 0, at the end of the first iteration - and index 1 should then become index 0, which subsequently will not be accessible at index 1, during the next iteration of the loop. just run the loop until the exit condition is met and then unset them all, not during the loop... or loop backwards, in order to keep the indexes intact; this would unset the last one element at first and the loop would not exceed the array boundaries.

having two different payment options within a single online order is rather an unlikely example, haven't seen this yet. people might rather post two orders (which implies, not only the business logic is flawed, but the array structure has an unfortunate design, which requires such messing around).

xdebug is great for understanding what is happening. even if my answer might not answer the question in code one can copy & paste (that's not my job), xdebug will tell you exactly what the problem is.

Upvotes: 0

Sohel0415
Sohel0415

Reputation: 9853

This should do your task:

$array = [
        "online" => [
            "IS-003" => [
                "quantity" => 1,
                "payment-option" => "online"
            ],
            "HA4" => [
                "quantity" => 1,
                "payment-option" => "online"
            ]
        ]
    ];


$code = "HA4";
$request_option = "cod";

foreach ($array as $paymentType => $details) {
        foreach ($details as $c => $p) {
            if ($c == $code) {
                $array[$request_option][$c] = $p;
                $array[$request_option][$c]["payment-option"] = $request_option;
                unset($array[$paymentType][$c]);
            }
        }
}

Upvotes: 1

Related Questions