我正在尝试删除所有带有重复数字的键,我尝试了一些此处发布的解决方案,例如我在脚本中使用的解决方案,但是这些解决方案都不适合我的目的。
这是我的数组:
至少重复了4个卡ID。
Array
(
[0] => Array
(
[id_card] => 11883834
[type] => 1
[registed] => 1547610891
)
[1] => Array
(
[id_card] => 20311077
[type] => 1
[registed] => 1547610891
)
[2] => Array
(
[id_card] => 16187903
[type] => 3
[registed] => 1547610891
)
[3] => Array
(
[id_card] => 16354099
[type] => 1
[registed] => 1547610891
)
[4] => Array
(
[id_card] => 21133393
[type] => 4
[registed] => 1547610891
)
[5] => Array
(
[id_card] => 15452852
[type] => 2
[registed] => 1547610891
)
[6] => Array
(
[id_card] => 19775869
[type] => 2
[registed] => 1547610891
)
[7] => Array
(
[id_card] => 20311077
[type] => 1
[registed] => 1547610891
)
[8] => Array
(
[id_card] => 21133393
[type] => 4
[registed] => 1547610891
)
[9] => Array
(
[id_card] => 11883834
[type] => 1
[registed] => 1547610891
)
)
1
此刻我有这样的东西:
<?php
$array_data = array_map('unserialize', array_unique(array_map('serialize', $myArray)));
echo '<pre>';
print_r($array_data);
echo '</pre>';
?>
只有10个键可以正常工作,但是例如50、100个键就无法使用。
任何帮助表示赞赏。
答案 0 :(得分:3)
所以这里的问题是array_unique
解决方案期望整个值是相等的-他们不只是根据您的ID字段进行比较。
相反,您可能希望遍历数组并跟踪您看到的ID,并仅获取那些以前从未看到过的ID的元素。
function filter_duplicate_id_cards($data) {
$seen = array(); // To keep track of the IDs we've seen
$filtered = array(); // Will hold the result
foreach($data as $item) {
if(array_key_exists($item['id_card'], $seen)) {
// We already encountered this id card before.
continue;
}
// Never-before seen id card, append it to the result and set the key in $seen
$filtered[] = $item;
$seen[$item['id_card']] = TRUE;
}
return $filtered;
}
请注意,这使用的是PHP数组的映射形式,而不是仅将可见的ID附加到列表形式,并使用in_array
之类的东西来检查是否已看到密钥。出于性能原因,这一点很重要,尤其是如果我们要处理大型数据集时-in_array
是O(n),数组中的项目数是array_key_exists
是O(1)。< / p>
此函数的通用版本如下所示:
function filter_duplicate_field($data, $field) {
$seen = array(); // To keep track of the keys we've seen
$filtered = array(); // Will hold the result
foreach($data as $item) {
if(array_key_exists($item[$field], $seen)) {
// We already encountered this key before.
continue;
}
// Never-before seen key, append it to the result and set the key in $seen
$filtered[] = $item;
$seen[$item[$field]] = TRUE;
}
return $filtered;
}
然后可以像$result = filter_duplicate_field($data, 'id_card');
这样称呼它。
答案 1 :(得分:2)
这不会保留原始的输入顺序,但是由于数据已建立索引,因此我认为这没关系。
在一个内胆中只有3个调用,您可以从后到前分配临时关联密钥,以消除后面的重复(因为php不允许重复密钥),然后可以选择使用array_values()
删除临时密钥。没有迭代的函数调用。没有查找数组。
代码:(Demo)
$array = [
['id_card' => 11883834, 'type' => 1, 'registed' => 1547610891],
['id_card' => 20311077, 'type' => 1, 'registed' => 1547610891],
['id_card' => 16187903, 'type' => 3, 'registed' => 1547610891],
['id_card' => 16354099, 'type' => 1, 'registed' => 1547610891],
['id_card' => 21133393, 'type' => 4, 'registed' => 1547610891],
['id_card' => 15452852, 'type' => 2, 'registed' => 1547610891],
['id_card' => 19775869, 'type' => 2, 'registed' => 1547610891],
['id_card' => 20311077, 'type' => 1, 'registed' => 1547610891],
['id_card' => 21133393, 'type' => 4, 'registed' => 1547610891],
['id_card' => 11883834, 'type' => 1, 'registed' => 1547610891]
];
var_export(array_values(array_column(array_reverse($array), null, 'id_card')));
如果您改变主意要保留第一次出现,可以删除array_reverse()
。如果输出中的第一级键不相关,则可以删除array_values()
。这些更改将使解决方案成为一个函数调用任务。
p.s。 “已注册 er ”