Laravel - удаление объекта внутри массива на основе значения ключа - array_filter - PullRequest
2 голосов
/ 09 июля 2019

У меня проблемы с удалением object внутри этого array.

Сначала я получаю $id, который должен быть удален из массива.Но когда я фильтрую, бросаю массив, добавляя к нему ключи.

Таким образом, логика больше не будет работать в остальной части приложения.

Как сохранить тот же синтаксис для объекта options после удаления объекта из массива cart?

enter image description here

    public function destroy( $id,  Request $request )
    {
        $user = $this->user ;

        $data = array_filter( $user->options->cart , function ( $option ) use ( $id ) {
            if ( $option->product_id ==  $id ) {
                return false;
            }
            return json_encode($option);
        });

        //dd($user->options->cart);
        //dd($data);

        $user->options = (object)['cart' => $data ];
        $user->save() ;
        return response()->json( $user , 200 ) ;

    }

Решено:

    public function destroy( $id,  Request $request )
    {
        $user = $this->user ;

        $data = array_filter( $user->options->cart , function ( $option ) use ( $id ) {
            if ( $option->product_id ==  $id ) {
                return false;
            }
            return true;
        });


        $user->options = ['cart' => array_values( $data ) ];
        $user->save() ;
        return response()->json( $user , 200 ) ;

    }
}

Ответы [ 3 ]

2 голосов
/ 09 июля 2019

если я вас правильно понял, вы хотите перестроить массив после выполнения вашей логики и сохранения структуры, я бы предложил вам использовать array_values ​​

$new_data= array_values($data);

и если вы получили ошибку, то это не массив, хотя я сомневаюсь, что просто используйте метод toArray ()

$new_data= array_values($data->toArray());
0 голосов
/ 09 июля 2019

Глядя на вашу кодировку JSON, я вижу, что ваш options объект в левом нижнем углу является объектом, который содержит свойство cart , которое является массивом. Ваш options объект в правом нижнем углу является объектом, который содержит свойство cart , которое является объектом , который содержит свойство для каждого числового индекса.

Я не совсем уверен, но я думаю, что проблема может быть в том, что array_filter функция сохраняет ключи массива :

Если функция обратного вызова возвращает TRUE, текущее значение из массива возвращается в массив результатов. Ключи массива сохранены.

Я предлагаю вам попробовать какой-то подход, который не пытается сохранить ключи массива, чтобы ваш фильтрованный массив имел непрерывные числовые значения.

public function destroy( $id,  Request $request )
{
    foreach($this->user->options->cart as $key => $cart_item) {
        if ($cart_item->product_id == $id) {
            unset($this->user->options->cart[$key]);
        }
    }

    $user->save() ;
    return response()->json( $user , 200 ) ;

}

РЕДАКТИРОВАТЬ: я не знаком с деталями вашей реализации (я не знаю, какой тип объекта $ user или что может делать $ user-> save или $ response-> json ()), но этот код удалить элемент массива по product_id:

$arr = array(
        (object)["product_id" => 819, "name" => "I am 819"],
        (object)["product_id" => 820, "name" => "I am 820"],
        (object)["product_id" => 821, "name" => "I am 821"],
        (object)["product_id" => 822, "name" => "I am 822"]
);


foreach($arr as $key => $v) {
        if ($v->product_id == 820) {
                unset($arr[$key]);
        }
}

var_dump($arr);

0 голосов
/ 09 июля 2019

Кажется, что (object)['cart' => $data ] как-то меняет ваш массив.

Установка свойства должна работать напрямую:

$user->options->cart = $data;

Кроме того, return json_encode($option); не имеет никакого реального эффекта, кромеделая выполнение медленнее.Вы можете просто return true;.

...