Php 从多维数组中删除所有重复数据

Php 从多维数组中删除所有重复数据,php,multidimensional-array,duplicates,filtering,Php,Multidimensional Array,Duplicates,Filtering,我试图删除所有重复编号的键,我尝试了一些在这里发布的解决方案,比如我在脚本中使用的解决方案,但都没有达到我的目的 这是我的阵列: 至少有4个卡ID重复 Array ( [0] => Array ( [id_card] => 11883834 [type] => 1 [registed] => 1547610891 ) [1] => Array

我试图删除所有重复编号的键,我尝试了一些在这里发布的解决方案,比如我在脚本中使用的解决方案,但都没有达到我的目的

这是我的阵列:

至少有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>';
?>
$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')));

只有10个键就可以很好地工作,但是当它使用50个或100个键时,就不再工作了


非常感谢您的帮助。

因此这里的问题是
数组\u unique
解决方案期望整个值是相等的-它们不只是根据您的ID字段进行比较

相反,您可能希望在数组中循环并跟踪您看到的ID,并且只获取您以前没有看到ID的元素

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;
}
请注意,这使用了PHP数组的映射形式,而不仅仅是将seed id附加到列表表单中,并使用类似于
in_array
的内容来检查我们是否看到了键。这对于性能来说很重要,特别是当我们要处理大型数据集时-
in_array
是O(n),带有数组中的#项,而
array_key_存在
是O(1)

此函数的更通用版本如下所示:

<?php
$array_data = array_map('unserialize', array_unique(array_map('serialize', $myArray)));
echo '<pre>';
print_r($array_data);
echo '</pre>';
?>
$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')));

然后您可以像这样调用它:
$result=filter\u duplicate\u field($data,'id\u card')

因此这里的问题是
数组_unique
解决方案期望整个值相等-它们不只是根据您的ID字段进行比较

相反,您可能希望在数组中循环并跟踪您看到的ID,并且只获取您以前没有看到ID的元素

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;
}
请注意,这使用了PHP数组的映射形式,而不仅仅是将seed id附加到列表表单中,并使用类似于
in_array
的内容来检查我们是否看到了键。这对于性能来说很重要,特别是当我们要处理大型数据集时-
in_array
是O(n),带有数组中的#项,而
array_key_存在
是O(1)

此函数的更通用版本如下所示:

<?php
$array_data = array_map('unserialize', array_unique(array_map('serialize', $myArray)));
echo '<pre>';
print_r($array_data);
echo '</pre>';
?>
$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')));

然后您可以像这样调用它:
$result=filter\u duplicate\u field($data,'id\u card')

这不会保留原始的输入顺序,但因为数据是索引的,所以我假设这不重要

一行代码中只有3个调用,您可以从后到前分配临时关联键以消除后面的重复项(因为php不允许重复键),然后可以选择使用
array\u values()
删除临时键。没有迭代函数调用。没有查找数组

代码:()

如果您改变主意要保留第一个匹配项,可以删除
array\u reverse()
。如果第一级键在输出中不相关,则可以删除
array\u values()
。这些更改将允许解决方案是一个单函数调用任务


p、 “registered”

一行代码中只有3个调用,您可以从后到前分配临时关联键以消除后面的重复项(因为php不允许重复键),然后可以选择使用
array\u values()
删除临时键。没有迭代函数调用。没有查找数组

代码:()

如果您改变主意要保留第一个匹配项,可以删除
array\u reverse()
。如果第一级键在输出中不相关,则可以删除
array\u values()
。这些更改将允许解决方案是一个单函数调用任务



p、 s.“注册ered”

重复元素中的
id\U卡
类型
注册的属性是否相同?如果不是,应该删除哪一个?不,它们并不总是相同的。如果有任何不同,我希望保留找到的第一个键。不同之处在于,当前代码在比较整个序列化阵列时无法工作。在这种情况下,有什么建议吗?重复元素中的所有
id\u卡
类型
注册
属性是否相同?如果不是,应该删除哪一个?不,它们并不总是相同的。如果有任何不同,我希望保留找到的第一个键。不同之处在于,在比较整个序列化阵列时,当前代码无法工作。在这种情况下,有什么建议吗?虽然此解决方案很聪明,也可能很有效,它的可读性不太好-您可能希望在代码中附带一条注释来解释它在做什么(或者将它封装在一个命名良好的函数中)。我喜欢本机函数的地方在于它们表达了它们的功能。您真的认为会有人看到
var\u导出(数组值(数组列(数组反($array),null,'id\u card'));
并立即想到“删除重复ID”?我对此表示怀疑。如果有人想在自定义函数中封装我的一行代码,或者在它前面加上注释块,或者声明3个一次性变量,我会很高兴。你看起来有点急躁。如果这是我的项目,我可能不会为3个函数调用中的2个而烦恼。这不需要函数包装器,只需要一个好的注释。漂亮整洁的解决方案。虽然这个解决方案很聪明,也可能很有效,但可读性不强-您可能希望在代码中附带一条注释来解释它在做什么(或者将其封装在一个命名良好的函数中)。我喜欢本机函数的地方在于它们表达了它们的功能。你真的认为有人会看
var_导出(数组_值(数组_列(数组_反向($array),null,'id_card'))
并立即想到“删除重复ID”?我对此表示怀疑。如果有人想用自定义函数包装我的一行程序,或者在它前面加一个