Map data from one object to another object by shared property value

yrdbyhpb  于 2022-10-22  发布在  PHP
关注(0)|答案(2)|浏览(187)

After decoding a json string that represents a multidimensional object array, I am trying to map one of its objects to another of its objects based on matching id values.
My input:

$data = array (
  0 => 
  (object) array(
     'products' => 
    array (
      0 => 
      (object) array(
         'Part ID' => '001',
         'name' => 'Product Name',
         'category' => 'Product Category',
         'description' => 'Product Description',
         'id' => '111xyz',
      ),
      1 => 
      (object) array(
         'Part ID' => '002',
         'name' => 'Product Name 2',
         'category' => 'Product Category 2',
         'description' => 'Product Description 2',
         'id' => '333xyz',
      ),
      2 => 
      (object) array(
         'Part ID' => '003',
         'name' => 'Product Name 3',
         'category' => 'Product Category 3',
         'description' => 'Product Description 3',
         'id' => '444xyz',
      ),
      3 => 
      (object) array(
         'Part ID' => '004',
         'name' => 'Product Name 4',
         'category' => 'Product Category',
         'description' => 'Product Description',
         'id' => '666xyz',
         'features_img_id' => 
        array (
          0 => 'f1',
          1 => 'f2',
          2 => 'f3',
        ),
      ),
    ),
  ),
  1 => 
  (object) array(
     'assets' => 
    array (
      0 => 
      (object) array(
         'File Name' => 'Some file name',
         'url' => 'www.123.com/x.jpg',
         'id' => '111xyz',
      ),
      1 => 
      (object) array(
         'File Name' => 'Feature 1 file',
         'url' => 'www.123.com/f1.jpg',
         'id' => 'f1',
      ),
      2 => 
      (object) array(
         'File Name' => 'Feature 2 file',
         'url' => 'www.123.com/f2.jpg',
         'id' => 'f2',
      ),
      3 => 
      (object) array(
         'File Name' => 'Feature 2 file',
         'url' => 'www.123.com/f3.jpg',
         'id' => 'f3',
      ),
    ),
  ),
);

Desired result:

Array
    (
        [0] => stdClass Object
            (
                [Part ID] => 001
                [name] => Product Name 1
                [category] => Product Category
                [description] => Product Description
                [url] => www.123.com/x.jpg
            )

        [1] => stdClass Object
            (
                [Part ID] => 002
                [name] => Product Name 2
                [category] => Product Category 2
                [description] => Product Description 2
            )

        [2] => stdClass Object
            (
                [Part ID] => 003
                [name] => Product Name 3
                [category] => Product Category 3
                [description] => Product Description 3
            )

        [3] => stdClass Object
            (
                [Part ID] => 004
                [name] => Product Name 4
                [category] => Product Category 4
                [description] => Product Description 4
                [feature_img-url] => Array
                (
                    [0] => www.123.com/f1.jpg
                    [1] => www.123.com/f3.jpg
                    [2] => www.123.com/f3.jpg
                )
            )
    )

Below is what I tried, but it is only producing the one array.

$data = json_decode($dData, false);
$products = $data[0]->products;
$assets = $data[1]->assets;

$newArr;
foreach ($products as $key => $value) {
    $newArr = $value->features_img;
}

$processedProducts = $products;
foreach ($processedProducts as $key => $product) {
    foreach ($assets as $asset) {
        if ($asset->id == $product->id) {
            $product->url = $asset->url;
        } elseif ($asset->id == in_array($asset->id, $newArr)) {
            $product->features_image_url = $asset->url;
        } else {
            //code
        }
    }
    unset($product->id);    
}    
print_r($processedProducts);

I don't know how to target the 'feature_img_id' array and match it with the assets ids and add it to the $processedProducts .

m4pnthwp

m4pnthwp1#

You can do it this way:

$dData = '[
            {
                "products": [
                    {
                        "Part ID" : "001",
                        "name" : "Product Name",
                        "category" : "Product Category",
                        "description" : "Product Description",
                        "id" : "111xyz"
                    },
                    {
                        "Part ID" : "002",
                        "name" : "Product Name 2",
                        "category" : "Product Category 2",
                        "description" : "Product Description 2",
                        "id" : "333xyz"
                    },
                    {
                        "Part ID" : "003",
                        "name" : "Product Name 3",
                        "category" : "Product Category 3",
                        "description" : "Product Description 3",
                        "id" : "444xyz"
                    },  
                    {
                        "Part ID" : "004",
                        "name" : "Product Name 4",
                        "category" : "Product Category",
                        "description" : "Product Description",
                        "id" : "666xyz",
                        "features_img_id":["f1","f2","f3"]
                    }]
                },
                {
                "assets": [
                    {
                        "File Name" : "Some file name",
                        "url" : "www.123.com/x.jpg",
                        "id" : "111xyz"
                    },
                    {
                         "File Name" : "Feature 1 file",
                        "url" : "www.123.com/f1.jpg",
                        "id" : "f1"
                    },
                    {
                         "File Name" : "Feature 2 file",
                        "url" : "www.123.com/f2.jpg",
                        "id" : "f2"
                    },
                    {
                         "File Name" : "Feature 2 file",
                        "url" : "www.123.com/f3.jpg",
                        "id" : "f3"
                    }]
            }
]';

$data = json_decode($dData, false);
$products = $data[0]->products;
$assets = $data[1]->assets;

$processedProducts = $products;
foreach($processedProducts as $key => $product) {
    foreach($assets as $asset) {
        if ($asset->id == $product->id) {
            $product->url = $asset->url;    
        }
        if (isset($product->features_img_id) && in_array($asset->id, $product->features_img_id)) {
            $product->feature_image_url[] = $asset->url;    
        }
    }
    unset($product->id);
    unset($product->features_img_id);
}

Will lead to the resulting array below:

Array
(
    [0] => stdClass Object
        (
            [Part ID] => 001
            [name] => Product Name
            [category] => Product Category
            [description] => Product Description
            [url] => www.123.com/x.jpg
        )

    [1] => stdClass Object
        (
            [Part ID] => 002
            [name] => Product Name 2
            [category] => Product Category 2
            [description] => Product Description 2
        )

    [2] => stdClass Object
        (
            [Part ID] => 003
            [name] => Product Name 3
            [category] => Product Category 3
            [description] => Product Description 3
        )

    [3] => stdClass Object
        (
            [Part ID] => 004
            [name] => Product Name 4
            [category] => Product Category
            [description] => Product Description
            [feature_image_url] => Array
                (
                    [0] => www.123.com/f1.jpg
                    [1] => www.123.com/f2.jpg
                    [2] => www.123.com/f3.jpg
                )

        )

)
ivqmmu1c

ivqmmu1c2#

  1. Decode your json as an object array.
  2. Create an associative map to find id-related values from the assets object.
  3. Loop the products data and push values which are found in the map.
  4. Loop over the inconsistently declared features_img_id data and push values which are found in the map.
  5. Unset the object properties that are unwanted.
    Code: ( Demo )
$map = array_column($array[1]->assets, 'url', 'id');

foreach ($array[0]->products as $obj) {
    if (isset($map[$obj->id])) {
        $obj->url = $map[$obj->id];
    }
    foreach ($obj->features_img_id ?? [] as $imgId) {
        if (isset($map[$imgId])) {
            $obj->feature_img_url[] = $map[$imgId];
        }
    }
    unset($obj->id, $obj->features_img_id);
}
var_export($array[0]->products);

相关问题