ssuhat
ssuhat

Reputation: 7656

PHP - Moving a key within an array and flatten it

I have this array of object:

[
  {
    "id": 1,
    "name": "Carbo",
    "menus": [
      {
        "id": 33,
        "name": "FloralWhite",
        "image": {
          "web": "https://lorempixel.com/640/360/food/?89722",
          "mobile": "https://lorempixel.com/640/360/food/?89722",
          "square": "https://lorempixel.com/640/360/food/?89722"
        },
        "logs": {
          "price": 2
        }
      },
      {
        "id": 40,
        "name": "LightGray",
        "image": {
          "web": "https://lorempixel.com/640/360/food/?63930",
          "mobile": "https://lorempixel.com/640/360/food/?63930",
          "square": "https://lorempixel.com/640/360/food/?63930"
        },
        "logs": {
          "price": 2
        }
      },
    ]
  }
]

What I want to achieve:

[
  {
    "id": 1,
    "name": "Carbo",
    "menus": [
      {
        "id": 33,
        "name": "FloralWhite",
        "image": {
          "web": "https://lorempixel.com/640/360/food/?89722",
          "mobile": "https://lorempixel.com/640/360/food/?89722",
          "square": "https://lorempixel.com/640/360/food/?89722"
        },
          "price": 2
      },
      {
        "id": 40,
        "name": "LightGray",
        "image": {
          "web": "https://lorempixel.com/640/360/food/?63930",
          "mobile": "https://lorempixel.com/640/360/food/?63930",
          "square": "https://lorempixel.com/640/360/food/?63930"
        },
          "price": 2
      },
    ]
    }
]

I've tried using laravel collection flatten with depth but it fail

$data = collect($data->menus);

$data = $data->flatten(1);
$data->values()->all();

How can I flatten the menus['logs'] object so it can one level with menu?

Upvotes: 0

Views: 110

Answers (2)

lazyCoder
lazyCoder

Reputation: 2561

@Stefen Suhat i really don't know what is the syntax for laravel but i did it with a simple php foreach() hope this will help you, as your array's depth is long so i had gone to all the levels of your array, check code and output snippet here https://eval.in/806879

try below one:

<?php
$array = array(
            array(
                   "id"=> 1,
                   "name"=> "Carbo",
                   "menus"=> array(
                   array(
                        "id"=> 33,
                        "name"=> "FloralWhite",
                        "image"=> array(
                          "web"=> "https=>//lorempixel.com/640/360/food/?89722",
                          "mobile"=> "https=>//lorempixel.com/640/360/food/?89722",
                          "square"=> "https=>//lorempixel.com/640/360/food/?89722"
                    ),
                    "logs"=> array(
                      "price"=> 2
                    )
                  ),
                  array(
                    "id"=> 40,
                    "name"=> "LightGray",
                    "image"=> array(
                      "web"=> "https=>//lorempixel.com/640/360/food/?63930",
                      "mobile"=> "https=>//lorempixel.com/640/360/food/?63930",
                      "square"=> "https=>//lorempixel.com/640/360/food/?63930"
                    ),
                    "logs"=> array(
                      "price"=> 2
                    )
                  ),
                )
            )
        );

foreach($array as $key => $value){
    foreach ($value as $key1 => $value1) {
        if(is_array($value1) && $key1 == "menus"){
            foreach($value1 as $key2 => $value2) {
                foreach ($value2 as $key3 => $value3) {
                    if(is_array($value3) && $key3 == "logs"){
                        unset($array[$key][$key1][$key2][$key3]);
                        $array[$key][$key1][$key2] = array_merge($array[$key][$key1][$key2], $value3);
                    }
                }

            }

        }
    }
}
echo "array after<br>";
echo "<pre>";
print_r($array); //your array after
?>

Upvotes: 0

Sotiris Kiritsis
Sotiris Kiritsis

Reputation: 3336

Something like this should do the trick. Simply iterate over your array, set the new property and remove the one you don't want.

        $data = json_decode("[{
        \"id\": 1,
        \"name\": \"Carbo\",
        \"menus\": [
            {
                \"id\": 33,
                \"name\": \"FloralWhite\",
                \"image\": {
                    \"web\": \"https://lorempixel.com/640/360/food/?89722\",
                    \"mobile\": \"https://lorempixel.com/640/360/food/?89722\",
                    \"square\": \"https://lorempixel.com/640/360/food/?89722\"
            },
            \"logs\": {
                \"price\": 2
            }
        },
        {
            \"id\": 40,
            \"name\": \"LightGray\",
            \"image\": {
                \"web\": \"https://lorempixel.com/640/360/food/?63930\",
                \"mobile\": \"https://lorempixel.com/640/360/food/?63930\",
                \"square\": \"https://lorempixel.com/640/360/food/?63930\"
            },
            \"logs\": {
                \"price\": 2
            }
        }
    ]
  }]");

foreach($data as $val){
    foreach($val->menus as $menuVal){
        $menuVal->price = $menuVal->logs->price;
        unset($menuVal->logs);
    }
}

Upvotes: 2

Related Questions