-2

How can I assign first level keys using a column value from the third level of a multidimensional array?

My input:

$array = [
    [
        ["ID" => 2, "vendor_id" => "37", "order_id" => 776],
    ],
    [
        ["ID" => 2, "vendor_id" => "37", "order_id" => 786],
    ]
];

My current output is like this:

array(1) {
[787]=>
  array(2) {
    [0]=>
    array(40) {
      ["ID"]=>
      string(1) "1"
      ["vendor_id"]=>
      string(2) "37"
      ["order_id"]=>
      string(3) "776"
    }
    [1]=>
    array(40) {
      ["ID"]=>
      string(1) "2"
      ["vendor_id"]=>
      string(2) "37"
      ["order_id"]=>
      string(3) "787"
    }
  }
}

I want to group the value of order_id separately as a key - the end result would look like this:

array(1) {
  [776]=>
  array(2) {
    [0]=>
    array(40) {
      ["ID"]=>
      string(1) "2"
      ["vendor_id"]=>
      string(2) "37"
      ["order_id"]=>
      string(3) "776"
    }
  }
  [787]=>
  array(2) {
    [0]=>
    array(40) {
      ["ID"]=>
      string(1) "2"
      ["vendor_id"]=>
      string(2) "37"
      ["order_id"]=>
      string(3) "787"
    }
  }
}
mickmackusa
  • 43,625
  • 12
  • 83
  • 136

3 Answers3

1

Get the current item or use reset and extract the entire columns indexing by order_id:

$result = array_column(current($array), null, 'order_id');

If there could be multiple arrays, then just loop and append:

$result = [];
foreach($array as $v) {
    $result += array_column($v, null, 'order_id');
}
AbraCadaver
  • 78,200
  • 7
  • 66
  • 87
0

you can use that function

//$array is your input array
//$mergedArray is the result wanted
$mergedArray = array_reduce($array, function($acc, $val) {
    foreach ($val as $order) {
        $acc[$order['order_id']] = $order;    
    }
    return $acc;
}, []);

you can try it on http://sandbox.onlinephpfunctions.com/

<?php
$array = [
    787 => [
        0 => [ "ID" => 1, "vendor_id" => "37", "order_id" => 776],
        1 => [ "ID" => 2, "vendor_id" => "37", "order_id" => 787],
        2 => [ "ID" => 1, "vendor_id" => "37", "order_id" => 790],
    ],
    734 => [
        0 => [ "ID" => 1, "vendor_id" => "37", "order_id" => 722],
        1 => [ "ID" => 2, "vendor_id" => "37", "order_id" => 735],
        2 => [ "ID" => 1, "vendor_id" => "37", "order_id" => 734],
    ],

];


$t = array_reduce($array, function($acc, $val) {
    foreach ($val as $order) {
        $acc[$order['order_id']] = $order;    
    }

    return $acc;
}, []);

var_dump($t);
Wonkledge
  • 1,732
  • 7
  • 16
0

The other answers do not maintain the multi-level structure described as your desired output. The order_id values must be used as first level keys, and the second level keys must be incremented/indexed as they are encountered. This will allow for multiple entries which share the same first level key.

foreach() inside of a foreach(): (Demo)

$result = [];
foreach ($array as $group) {
    foreach ($group as $row) {
        $result[$row['order_id']][] = $row;
    }
}
var_export($result);

array_reduce() with foreach(): (Demo)

var_export(
    array_reduce(
        $array,
        function ($carry, $group) {
            foreach ($group as $row) {
                $carry[$row['order_id']][] = $row;
            }
            return $carry;
        }
    )
);
mickmackusa
  • 43,625
  • 12
  • 83
  • 136