我一直在尝试找出两个集合之间的差异:
第一:
{
"name": "Test A",
"scores": [
{
"name": "Values",
"points": 9
},
{
"name": "Algebra",
"points": 6
},
{
"name": "Science",
"points": 5
},
{
"name": "Total",
"points": 20
}
]
}
第二:
{
"name": "Test A",
"scores": [
{
"name": "Values",
"points": 5
},
{
"name": "Algebra",
"points": 8
},
{
"name": "Total",
"points": 13
}
]
}
我的目标是基于第一个集合创建一个包含缺失键和值对的新集合,保留其值,缺失键的值为 0。我想要实现的输出是:
{
"name": "Test A",
"scores": [
{
"name": "Values",
"points": 5
},
{
"name": "Algebra",
"points": 8
},
{
"name": "Science",
"points": 0
},
{
"name": "Total",
"points": 13
}
]
}
使用 diffKeys 方法:
$collection_new = $collection_1['scores']->diffKeys($collection_2['scores']);
dd($collection_new->all());
这将导致:
{
"4": {
"name": "Total",
"points": 20
},
}
需要您的精彩投入。谢谢。
由于假定第一个数组包含第二个数组中所有可能遇到的名称,因此只需迭代第一个数组,通过引用修改点元素,将所有值默认为 0,然后为点元素创建查找引用。
然后循环第二个数组并将其所有值映射到相应的第一个数组数据以覆盖初始的 0 值。
代码:(演示)
foreach ($first['scores'] as ['name' => $name, 'points' => &$points]) {
$points = 0;
$refPoints[$name] =& $points;
}
foreach ($second['scores'] as ['name' => $name, 'points' => $refPoints[$name]]);
var_export($first);
下面的函数应该可以工作,但第一个数组应该包含第二个数组的所有分数。
$first['scores'] = mergeScores();
function mergeScores()
{
return array_map(
fn ($x) => array_merge($x, getPoint($x['name'])),
$first['scores']
);
}
function getPoint($name)
{
$score = array_filter($second, fn ($x) => $x['name'] == $name);
return ['point' => empty($score) ? 0 : $score['score']];
}