I need to make order in the data structure of my product attributes in woocommerce, grouping each attribute and its values.
My array now
array (size=5)
0 =>
array (size=1)
'pa_color' =>
array (size=1)
0 => string 'red' (length=3)
1 =>
array (size=1)
'pa_color' =>
array (size=1)
0 => string 'red' (length=3)
2 =>
array (size=2)
'pa_color' =>
array (size=1)
0 => string 'gray' (length=4)
'pa_modello' =>
array (size=1)
0 => string 'modello2' (length=8)
3 =>
array (size=1)
'pa_color' =>
array (size=1)
0 => string 'yellow' (length=6)
4 =>
array (size=0)
empty
I need to merge in something like:
array (size=1)
'pa_color' =>
array (size=1)
0 => string 'red' (length=3)
1 => string 'gray' (length=4)
2 => string 'yellow' (length=6)
'pa_modello' =>
array (size=1)
0 => string 'modello2' (length=8)
grouping the values of the same keys in one array.
thanks in advance
4
Answers
Let
$array
is your array:This should do the job.
EDIT:
For dynamic attributes comment:
It looks complicated .. I can’t find a better approach.
Loop through the first level of entries, then added a nest loop to create variables from the desired keys and values from the subarrays.
Because your deepest subarray only has one element in it, you can use "array destructuring" inside of the nested loop to assign the lone element value as
$value
.Ensure unique values in the output by declaring the
$value
as the deep value’s key in the result array.If you truly want the subarrays to be re-indexed, you can use
array_map()
andarray_values()
for this — but only do this if necessary.Code: (Demo)
Output:
p.s. If your deep subarrays might have more than one element, then just accommodate that with another loop to iterate that level.
Translated to the code that you wrote in your self-answering post, I think it might look like this:
Th easiest way to combine the array would be to use
array_merge_recursive
with the splat operator (...
) on the array of arrays.The splat operator would unpack the array that can be used to merge them recursively.
Also if you need only unique values in the merged array you can use
array_map
like thismore about splat operator
Edit after comments
Because I have been heavily using this approach myself I made some tests to see which one is faster.
Sharing the results:
Question: Which is faster between the two methods?
Method 1:
array_map('array_unique', array_merge_recursive(...$array));
Method 2: Using
foreach
as explained in mickmackusa’s answerTesting with arrays sized 5, 50, 100 and 500
Looping each function by 10000 and 100000.
T1 is time taken by
array_merge_recursive
and T2 is time taken byforeach
Conclusion:
foreach
takes 16.1562 secs moreTherefore, if you have smaller arrays use whatever you want. For bigger arrays definitely avoid
foreach
and usearray_merge_recursive
Link to test sandbox