4

Is there function that works similar to array_column for multidimensional arrays? Is there a function that translates the first array below to the second:

Array
(
    [0] => Array
        (
            [foodType] => fruits
            [itemID] => 1
            [itemName] => apple
        )

    [1] => Array
        (
            [foodType] => fruits
            [itemID] => 2
            [itemName] => banana
        )

    [2] => Array
        (
            [foodType] => veggies
            [itemID] => 3
            [itemName] => carrot
        )

    [3] => Array
        (
            [foodType] => veggies
            [itemID] => 4
            [itemName] => broccoli
         )

)

Resulting array:

Array
(
    [fruits] => Array
        (
            [0] => Array
                (
                    [itemID] => 1
                    [itemName] => apple
                )

            [1] => Array
                (
                    [itemID] => 2
                    [itemName] => banana
                )

        )

    [veggies] => Array
        (
            [0] => Array
                (
                    [itemID] => 3
                    [itemName] => carrot
                )

            [1] => Array
                (
                    [itemID] => 4
                    [itemName] => broccoli
                 )
        )

)
Athul Nath
  • 2,536
  • 1
  • 15
  • 27
jcropp
  • 1,236
  • 2
  • 10
  • 29
  • https://stackoverflow.com/a/39208133/2943403 – mickmackusa Aug 10 '20 at 11:16
  • While not solving the question, this is a good reference for what will happen if you use just `array_column` for the array https://stackoverflow.com/questions/40239505/multidimensional-indexed-array-to-associative-array-depending-on-column-value – Ng Sek Long Dec 15 '21 at 09:44

4 Answers4

4

No, there is not a function to get your expected output natively, though you can make your own functions, just use array_column to get the types/column, and then loop over your array, on match remove the item as to not duplicate iterations.

Something like:

<?php
$data = [
    ['foodType' => 'fruits', 'itemID' => 1, 'itemName' => 'apple'],
    ['foodType' => 'fruits', 'itemID' => 2, 'itemName' => 'banana'],
    ['foodType' => 'veggies', 'itemID' => 3, 'itemName' => 'carrot'],
    ['foodType' => 'veggies', 'itemID' => 4, 'itemName' => 'broccoli']
];

function array_column_multi ($array, $column) {
    $types = array_unique(array_column($array, $column));

    $return = [];
    foreach ($types as $type) {
        foreach ($array as $key => $value) {
            if ($type === $value[$column]) {
                unset($value[$column]);
                $return[$type][] = $value;
                unset($array[$key]);
            }
        }
    }
    return $return;
}


print_r(array_column_multi($data, 'foodType'));

https://3v4l.org/KQVeN

Result:

Array
(
    [fruits] => Array
        (
            [0] => Array
                (
                    [itemID] => 1
                    [itemName] => apple
                )

            [1] => Array
                (
                    [itemID] => 2
                    [itemName] => banana
                )

        )

    [veggies] => Array
        (
            [0] => Array
                (
                    [itemID] => 3
                    [itemName] => carrot
                )

            [1] => Array
                (
                    [itemID] => 4
                    [itemName] => broccoli
                )

        )

)
Lawrence Cherone
  • 46,049
  • 7
  • 62
  • 106
0

Oh I just noticed that you're aggregating them by ID. There's not a function for that, you're going to need to iterate over the input with a loop, and populate an output array with the data you want. Eg:

$output = [];

foreach($input_array as $item) {
  $output[$item['id']][] = [
     'itemID' => $item['itemID'],
     'itemName' => $item['itemName']
  ];
}
Sammitch
  • 30,782
  • 7
  • 50
  • 77
-1

Quite old question, but I hope it help someone. Unfortunately there's no native function yet but output is achievable using php's array_filter():

$foods = [
    [
        'foodType' => 'fruits',
        'itemID' => 1,
        'itemName' => 'apple',
    ],

    [
        'foodType' => 'fruits',
        'itemID' => 2,
        'itemName' => 'banana',
    ],

    [
        'foodType' => 'veggies',
        'itemID' => 3,
        'itemName' => 'carrot',
    ],

    [
        'foodType' => 'veggies',
        'itemID' => 4,
        'itemName' => 'broccoli',
    ]

];

$grouped_foods = [];
$groupByColumn = 'foodType';

array_filter($foods, function ($foodItem) use(&$grouped_foods, $groupByColumn) {
    $grouped_foods[$foodItem[$groupByColumn]][] = array_filter($foodItem, function ($key) use($groupByColumn) {
        return $key != $groupByColumn;
    }, ARRAY_FILTER_USE_KEY);
});


echo "<pre>";
print_R($grouped_foods);
echo "</pre>";

see in action: https://3v4l.org/bbX5A

Disclaimer: for/foreach loops are significantly faster in performance than native array functions.

Muhammad Sheraz
  • 569
  • 6
  • 11
-1

I prefer using the following solution.

Example

  "allergens" => array:5 [
    0 => array:2 [
      "id" => "10"
      "object" => array:1 [
        "allergens" => "10"
      ]
    ]
    1 => array:2 [
      "id" => "11"
      "object" => array:1 [
        "allergens" => "11"
      ]
    ]
    2 => array:2 [
      "id" => "4"
      "object" => array:1 [
        "allergens" => "4"
      ]
    ]
  ]

Giving this example, if you would like an array containing only the value of allergens then use the following code.

Solution

$allergens = array_map( function ( $ar ) {
   return $ar['allergens'];
}, array_column( $allergensArr, 'object' ) );

Result

array:5 [
  0 => "10"
  1 => "11"
  2 => "4"
]
Unicco
  • 2,466
  • 1
  • 26
  • 30