I need to group data in a multidimensional array data which can be related on a single column entry_id
.
In addition to the entry_id
there are other columns that will also be identical in other related rows (ic
, name
, and residency
). While grouping, these data points can simply be overwritten — in other words, I don’t need to collect multiple copies of the same value within the respective group.
Finally, there will be data points within respective groups that will differ — these values need to stored as subarrays within the groups so that no data is lost.
If there is only one row’s data in a group, the file_no
and detail
data does not need to be converted to an array. This means that the result array will have variable depth — some rows will flat and other may be 2 dimensional.
Sample input:
$array = [ [ 'entry_id' => 1, 'ic' => 2147483647, 'name' => 'Kořínková Blanka', 'residency' => 'Štětí, Lukešova 354, 411 08', 'file_no' => 'KSUL 77 INS 18898 / 2013', 'detail' => '749371da-725c-4738-8def-2f7167142a6f' ], [ 'entry_id' => 1, 'ic' => 2147483647, 'name' => 'Kořínková Blanka', 'residency' => 'Štětí, Lukešova 354, 411 08', 'file_no' => 'KSUL 77 INS 21218 / 2013', 'detail' => '43b6a718-4647-451d-9c53-50dfee8403ff' ], [ 'entry_id' => 2, 'ic' => 46900217, 'name' => 'ENTEC a.s. "v likvidaci"', 'residency' => 'Staré Město, Brněnská 1916, 686 03', 'file_no' => 'KSBR 28 INS 1232 / 2013', 'detail' => 'e2155a52-c464-4357-b71b-4f4ff75585eb' ], ];
Desired output (based on same ‘entry_id’ grouping):
Array ( [0] => Array ( [entry_id] => 1 [ic] => 2147483647 [name] => Kořínková Blanka [residency] => Štětí, Lukešova 354, 411 08 [file_no] => Array ( [0] => KSUL 77 INS 18898 / 2013 [1] => KSUL 77 INS 21218 / 2013 ) [detail] => Array ( [0] => A749371da-725c-4738-8def-2f7167142a6f [1] => 43b6a718-4647-451d-9c53-50dfee8403ff ) ) [1] => Array ( [entry_id] => 2 [ic] => 46900217 [name] => ENTEC a.s. "v likvidaci" [residency] => Staré Město, Brněnská 1916, 686 03 [file_no] => KSBR 28 INS 1232 / 2013 [detail] => e2155a52-c464-4357-b71b-4f4ff75585eb ) )
Advertisement
Answer
Your issue can be resolved with one functional block, using array_reduce()
and array_merge()
principles:
$mergeId = 'entry_id'; $data = array_reduce($data, function($c, $x) use ($mergeId) { $c[$x[$mergeId]] = isset($c[$x[$mergeId]]) ?array_combine( $z=array_keys($c[$x[$mergeId]]), array_map(function($y) use ($x, $c, $mergeId) { return in_array($x[$y], (array)$c[$x[$mergeId]][$y]) ?$c[$x[$mergeId]][$y] :array_merge((array)$c[$x[$mergeId]][$y], [$x[$y]]); }, $z) ) :$x; return $c; }, []);
you may want to apply array_values()
if you need to re-index result set (so keys would be consecutive, starting from 0
). Check the fiddle.