我有两个数组,必须在
dt_date
列上合并在一起,并且我需要在结果的所有行中声明 subscribers
和 unsubscribers
。
$array1 = [
['subscribers' => 2, 'dt_date' => '2014-02-27'],
['subscribers' => 2, 'dt_date' => '2014-02-25'],
['subscribers' => 1, 'dt_date' => '2014-02-07']
];
$array2 = [
['unsubscribers' => 1, 'dt_date' => '2014-02-27'],
['unsubscribers' => 1, 'dt_date' => '2014-02-01']
];
我需要从两个数组创建一个如下所示的数组。
[
['subscribers' => 2, 'unsubscribers' => 1, 'dt_date' => '2014-02-27'],
['subscribers' => 2, 'unsubscribers' => 0, 'dt_date' => '2014-02-25'],
['subscribers' => 1, 'unsubscribers' => 0, 'dt_date' => '2014-02-07'],
['subscribers' => 0, 'unsubscribers' => 1, 'dt_date' => '2014-02-01']
]
我试过了
$result = array_merge_recursive($aray1, $array2);
并且
$result = array_merge(
$array1,
array_udiff(
$array2,
$array1,
function($array1,$array2){
return strcmp($array1['dt_date'],$array2['dt_date']);
}
)
);
但是结果却没有想象中的那样
实际上,你的问题可以用一些
foreach
的东西来解决,但我注意到你正在尝试模拟某种 SQL JOIN
行为(将 ON
列作为 dt_date
)。这就是为什么我花了更多时间并创建了更常见的解决方案。
首先,我们需要重新索引数组,以便我们可以更快地使用它们:
function reindexArray($array, $column)
{
return array_combine(
array_map(function($x) use ($column)
{
return $x[$column];
}, $array),
$array
);
}
array_column()
调用替换,但我假设你有 PHP 5.3,因此你需要“手动”重新索引。
接下来,加入逻辑:
function arrayJoin($array1, $array2, $column, $default=null)
{
//in PHP 5.5 it's just array_column() call:
$array1 = reindexArray($array1, $column);
$array2 = reindexArray($array2, $column);
$blank1 = array_combine(
array_keys(current($array1)),
array_fill(1, count(current($array1)), $default)
);
$blank2 = array_combine(
array_keys(current($array2)),
array_fill(1, count(current($array2)), $default)
);
unset($blank1[$column], $blank2[$column]);
return array_merge(
array_map(function($x) use ($array1, $blank2)
{
return array_merge($array1[$x], $blank2);
}, array_keys(array_diff_key($array1, $array2))),
array_map(function($x) use ($array1, $array2)
{
return array_merge($array1[$x], $array2[$x]);
}, array_keys(array_intersect_key($array1, $array2))),
array_map(function($x) use ($array2, $blank1)
{
return array_merge($array2[$x], $blank1);
}, array_keys(array_diff_key($array2, $array1)))
);
}
- 正如您所看到的,您还需要决定如何处理每个连接数组的未设置键。
$default
将为您填写该值。因此,您的问题将通过以下方式解决:
$result = arrayJoin($array1, $array2, 'dt_date', 0);
-检查这个演示。
但是,如果您的原始数组源自某些 SQL 数据库,那么更好的做法是将
JOIN
逻辑放在那里 - 因为数据库的目的是存储数据并正确选择它。
我找到答案了
$result= array_replace_recursive($array1,$array2);
foreach ($result as $key => $value) {
if(!isset($value['unsubscribers']))
$result[$key]['unsubscribers']=0;
if(!isset($value['subscribers']))
$result[$key]['subscribers']=0;
}
谢谢你
array_values()
重新索引结果数组(这会删除临时的第一级键)。代码:(演示)
$result = [];
$default = array_fill_keys(['subscribers', 'unsubscribers'], 0);
foreach (array_merge($array1, $array2) as $row) {
$result[$row['dt_date']] = array_merge($result[$row['dt_date']] ?? $default, $row);
}
var_export(array_values($result));
功能风格的等价物:(Demo)
$default = array_fill_keys(['subscribers', 'unsubscribers'], 0);
var_export(
array_values(
array_reduce(
array_merge($array1, $array2),
function($result, $row) use($default) {
$result[$row['dt_date']] = array_merge($result[$row['dt_date']] ?? $default, $row);
return $result;
}
)
)
);