我花了数小时试图找到这个问题的答案,但我一直在努力。我相当熟悉PHP和各种内置函数,并且可以构建一个复杂的foreach()循环来执行此操作,但是我认为我想问问是否有人对我的问题有更明智的解决方案。
我有以下带有三个“行”的简化示例数组(实际数组通常更大,更复杂,但问题是相同的)。
$rows[] = [
"widget_id" => "widget1",
"size" => "large",
"item" => [
"item_id" => "item1",
"shape" => "circle",
"paint" => [
"paint_id" => "paint1",
"colour" => "red",
]
]
];
# Exactly the same as above, except the "paint" child array is different
$rows[] = [
"widget_id" => "widget1",
"size" => "large",
"item" => [
"item_id" => "item1",
"shape" => "circle",
"paint" => [
"paint_id" => "paint2",
"colour" => "green",
]
]
];
# Same children ("item" and "paint") as the first row, but different parents ("widget_id" is different)
$rows[] = [
"widget_id" => "widget2",
"size" => "medium",
"item" => [
"item_id" => "item1",
"shape" => "circle",
"paint" => [
"paint_id" => "paint1",
"colour" => "red",
]
]
];
我想要得到的是以下输出:
[[
"widget_id" => "widget1",
"size" => "large",
"item" => [
"item_id" => "item1",
"shape" => "circle",
"paint" => [[
"paint_id" => "paint1",
"colour" => "red",
],[
"paint_id" => "paint2",
"colour" => "green",
]]
]
],[
"widget_id" => "widget2",
"size" => "medium",
"item" => [
"item_id" => "item1",
"shape" => "circle",
"paint" => [
"paint_id" => "paint1",
"colour" => "red",
]
]
]]
基本上,当两行共享相同的键和值时,请合并它们。当键相同但值不同时,请保留两个值并将它们放在键下的数字数组中(类似如何array_merge_recursive
操作)。
挑战在于值本身可以是数组,并且级别数未知。是否有一种聪明而有效的方法来执行此操作,还是我必须诉诸繁重的工作foreach
循环?
感谢您的浏览,希望有比我更聪明的人阅读本文!
我通过以下功能获得了预期的数组结构,希望其中的注释是明确的:
function complex_merge(array $arr): array
{
// Grouped items
$result = [];
$iterationKey = 0;
// Loop through every item
while (($element = array_shift($arr)) !== null) {
// Save scalar values as is
$scalarValues = array_filter($element, 'is_scalar');
// Save array values in an array
$arrayValues = array_map(fn(array $arrVal) => [$arrVal], array_filter($element, 'is_array'));
$arrayValuesKeys = array_keys($arrayValues);
$result[$iterationKey] = array_merge($scalarValues, $arrayValues);
// Compare with remaining items
for ($i = 0; $i < count($arr); $i++) {
$comparisonScalarValues = array_filter($arr[$i], 'is_scalar');
// Scalar values are same, add the array values to the containing arrays
if ($scalarValues === $comparisonScalarValues) {
$comparisonArrayValues = array_filter($arr[$i], 'is_array');
foreach ($arrayValuesKeys as $arrayKey) {
$result[$iterationKey][$arrayKey][] = $comparisonArrayValues[$arrayKey];
}
// Remove matching item
array_splice($arr, $i, 1);
$i--;
}
}
// Merge array values
foreach ($arrayValuesKeys as $arrayKey) {
$result[$iterationKey][$arrayKey] = complex_merge($result[$iterationKey][$arrayKey]);
// array key contains a single item, extract it
if (count($result[$iterationKey][$arrayKey]) === 1) {
$result[$iterationKey][$arrayKey] = $result[$iterationKey][$arrayKey][0];
}
}
// Increment result key
$iterationKey++;
}
return $result;
}
只需传递$rows
给函数,即可快速检查值:
echo '<pre>' . print_r(complex_merge($rows), true) . '</pre>';
/*
Displays:
Array
(
[0] => Array
(
[widget_id] => widget1
[size] => large
[item] => Array
(
[item_id] => item1
[shape] => circle
[paint] => Array
(
[0] => Array
(
[paint_id] => paint1
[colour] => red
)
[1] => Array
(
[paint_id] => paint2
[colour] => green
)
)
)
)
[1] => Array
(
[widget_id] => widget2
[size] => medium
[item] => Array
(
[item_id] => item1
[shape] => circle
[paint] => Array
(
[paint_id] => paint1
[colour] => red
)
)
)
)
*/
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句