Search code examples
phparrayslaravellaravel-5.3

Laravel 5.3 - Merge array based on 2 matching keys?


Given the following two arrays, how can they be merged efficiently to result in the third array? productData

$productData =
[
  {
    "product_id": 4,
    "type": "electronic",
    "name": "monitor",
    "specs": {
      "HDMI": true,
      "VGA": false
    }
  },
  {
    "product_id": 5,
    "type": "electronic",
    "name": "HDMI cable",
    "specs": {
      "length": "3ft"
    }
  },
  {
    "product_id": 6,
    "type": "kitchen",
    "name": "spoon"
  }
]

products

$products =
{
  "products": 3,
  "per_page": 10,
  "current_page": 1,
  "data": [
    {
      "id": 4,
      "product_type": "electronic",
      "product_id": 6
    },
    {
      "id": 6,
      "type": "electronic",
      "product_id": 5
    },
    {
      "id": 9,
      "type": "kitchen",
      "product_id": 4
    }
  ]
}

productsFinal ($productData merged into $products - based on matching combo of product_id/product_id and type/product_type)

$productsFinal = 
{
  "products": 3,
  "per_page": 10,
  "current_page": 1,
  "data": [
    {
      "id": 4,
      "product_type": "electronic",
      "product_id": 6,

      // How to merge product data and wrap with "data" key
      "data": {
        "product_id": 6,
        "type": "kitchen",
        "name": "spoon"
      }

    },
    {
      "id": 6,
      "type": "electronic",
      "product_id": 5,

      // How to merge product data and wrap in "data" key
      "data": {
        "product_id": 5,
        "type": "electronic",
        "name": "HDMI cable",
        "specs": {
          "length": "3ft"
        }
      }
    },
    {
      "id": 9,
      "type": "kitchen",
      "product_id": 4,

      // How to merge product data and wrap in "data" key
      "data": {
        "product_id": 6,
        "type": "kitchen",
        "name": "spoon"
      }
    }
  ]
}

I tried different things for the outcome in a foreach loop but still cannot get it to render as intended:

foreach($productData as $productDataItem) {
  // when $productDataItem.product_id == $product.product_id && $productDataItem.type == $product.product_type
  // move the matching $productDataItem object into matching $product object, wrapped in a new "data" key
}

Solution

  • I don't know Laravel too well. However you can join your data objects quite easily:

    <?php
    $productData = json_decode('[
      {
        "product_id": 4,
        "type": "electronic",
        "name": "monitor",
        "specs": {
          "HDMI": true,
          "VGA": false
        }
      },
      {
        "product_id": 5,
        "type": "electronic",
        "name": "HDMI cable",
        "specs": {
          "length": "3ft"
        }
      },
      {
        "product_id": 6,
        "type": "kitchen",
        "name": "spoon"
      }
    ]');
    
    $products = json_decode('{
      "products": 3,
      "per_page": 10,
      "current_page": 1,
      "data": [
        {
          "id": 4,
          "type": "electronic",
          "product_id": 6
        },
        {
          "id": 6,
          "type": "electronic",
          "product_id": 5
        },
        {
          "id": 9,
          "type": "kitchen",
          "product_id": 4
        }
      ]
    }');
    
    // combine both data objects 
    
    foreach($products->data As &$p) {
        foreach($productData As $d) {
            if(property_exists($p, "product_id") && property_exists($d, "product_id") && property_exists($p, "type") && property_exists($d, "type")) {
                if($p->product_id==$d->product_id && $p->type==$d->type) {
                    //$p = (object) array_merge((array) $p, (array) $d);
                    $p->data = $d; // updated answer
                    continue;
                }
            }
        }
    }
    
    echo("<pre>");
    echo json_encode($products, JSON_PRETTY_PRINT);
    
    
    ?>
    

    You can test the code here: http://sandbox.onlinephpfunctions.com/code/98a50c35ee32c30f0d2be1661f7afb5895174cbe Update: http://sandbox.onlinephpfunctions.com/code/aeebfdcf4f4db5e960260e931982570cfed19e0e