4

I have an array:

[['a', 1], ['b', 1], ['c',2], ['d',2]]

How can I group the subarrays based on the second column value like this:

[[['a', 1], ['b', 1]], [['c',2], ['d',2]]]

I have an idea to solve this with a foreach, but it may have a way with the built-in functions?

Sketch with foreach:

$in = [['a', 1], ['b', 1], ['c',2], ['d',2]];
$out = [];

foreach($in as $i) {
    $out[$i[1]][] = $i;
}
mickmackusa
  • 33,121
  • 11
  • 58
  • 86
Ticksy
  • 551
  • 2
  • 10
  • 19
  • Can you alter the format of the input array? – Matthemattics Apr 10 '12 at 16:15
  • 2
    Do you want to always split it in half or in sets of two? – Kasapo Apr 10 '12 at 16:18
  • [Here's the list of PHP built-in array functions](http://www.php.net/manual/en/ref.array.php) – Matthemattics Apr 10 '12 at 16:19
  • @Kasapo No. It can be split many parts. – Ticksy Apr 10 '12 at 16:22
  • @Lübnah About the list of built-in functions, I know. But in this task, I do not know how to use them. And is it possible at all. Can you rephrase your first question? Unfortunately, I do not understand. – Ticksy Apr 10 '12 at 16:24
  • If the 2nd element in the inner arrays always refer to the index of the "column" it belongs to, then your solution is fine. I don't really think there's anything built in for this. – Kasapo Apr 10 '12 at 16:25
  • @Ticksy Sorry, what I meant was, are you in control of the way that data is originally formatted? E.g., do you have control of the data source? – Matthemattics Apr 10 '12 at 16:32
  • 1
    This is an array grouping problem, your approach is correct assuming you are not building `$in` (if you are, just build it grouped). See more @ http://stackoverflow.com/questions/2189626/php-how-to-group-a-multidimensional-array-by-a-particular-value – connec Apr 10 '12 at 16:55

3 Answers3

1

You more or less have what I would have arrived at for a solution.

As long as the data that you wish to use as an index will always be in the same position in the array, you will be able to hardcode the index as you have done in the collector array.

If not, I would think about moving to an associative array and assigning a name to the value that you want to use as an index when creating the array.

[['a', 'index'=>1] [etc...]]

$out[$i[index]][] = $i;
Malovich
  • 891
  • 5
  • 14
0

There isn't a native php function that will group on the column value of an indexed array of indexed arrays. If you were talking about associative arrays, the array_merge_recursive() might be of interest.

(Demo)

Basic loop syntax: (more concise, usually faster)

$result = [];
foreach ($array as $row) {
    $result[$row[1]][] = $row;
}
var_export($result);

Functional syntax: (more declarative, no new global variable declared)

var_export(
    array_reduce(
        $array,
        function ($carry, $row) {
            $carry[$row[1]][] = $row;
            return $carry;
        }
    )
);

If you wish to re-index the result (remove the group keys), then call array_values() on the result.

mickmackusa
  • 33,121
  • 11
  • 58
  • 86
-1

The only PHP built-in that's specific to multi-dimensional arrays seems to be array_multisort, which won't be of much help unless there are assumptions we can make about the data contained within the input array.

In the case of a small dataset, your brute-force example seems fine to me.

Matthemattics
  • 8,354
  • 1
  • 18
  • 18