【问题标题】:How to remove duplicate values from a multidimensional array?如何从多维数组中删除重复值?
【发布时间】:2018-01-18 02:33:59
【问题描述】:

我有来自两个单独的 mysql 查询的数组数据。数组数据如下所示:

0
:
{user_id: 82, ac_type: 1,…}
1
:
{user_id: 80, ac_type: 5,…}
2
:
{user_id: 76, ac_type: 1,…}
3
:
{user_id: 82, ac_type: 1,…}
4
:
{user_id: 80, ac_type: 5,…}

我想删除重复的数组项。

所以,我的输出会是这样的:

0
:
{user_id: 82, ac_type: 1,…}
1
:
{user_id: 80, ac_type: 5,…}
2
:
{user_id: 76, ac_type: 1,…}

我想通过 user_id 检查重复。

我尝试了以下解决方案,但都没有按预期工作。

$input = array_unique($res, SORT_REGULAR);

$input = array_map("unserialize", array_unique(array_map("serialize", $res)));

下面我也试过了。

$results = array();

foreach ($res as $k => $v) {
        $results[implode($v)] = $v;
}

$results = array_values($results);
print_r($results);

但仍然存在重复数据。

【问题讨论】:

  • 哇,我看到了反对票。有什么具体原因吗?
  • 我也不赞成。猜猜这是在这个时间问的风险。许多用户为徽章或其他东西随机投票..
  • @icecub 我试图正确解释问题。还搜索了答案。还提到了我尝试过的。但仍然被否决。
  • 我只能看到有人试图编辑您的问题标题。但就是这样。让我纠正它。
  • 谢谢你。我从昨天开始就在尝试解决这个问题,但到目前为止还没有成功。

标签: php multidimensional-array duplicates filtering


【解决方案1】:

花了我一段时间,但这应该可行(cmets 中的解释):

<?php

/* Example array */
$result = array(
    0 => array(
        "user_id" => 82,
        "ac_type" => 1
        ),
    1 => array(
        "user_id" => 80,
        "ac_type" => 5
        ),
    2 => array(
        "user_id" => 76,
        "ac_type" => 1
        ),
    3 => array(
        "user_id" => 82,
        "ac_type" => 2
        ),
    4 => array(
        "user_id" => 80,
        "ac_type" => 2
        )
);

/* Function to get the keys of duplicate values */
function get_keys_for_duplicate_values($my_arr, $clean = false) {
    if ($clean) {
        return array_unique($my_arr);
    }

    $dups = $new_arr = array();
    foreach ($my_arr as $key => $val) {
      if (!isset($new_arr[$val])) {
         $new_arr[$val] = $key;
      } else {
        if (isset($dups[$val])) {
           $dups[$val][] = $key;
        } else {
           //$dups[$val] = array($key);
           $dups[] = $key;
           // Comment out the previous line, and uncomment the following line to
           // include the initial key in the dups array.
           // $dups[$val] = array($new_arr[$val], $key);
        }
      }
    }
    return $dups;
}

/* Create a new array with only the user_id values in it */
$userids = array_combine(array_keys($result), array_column($result, "user_id"));

/* Search for duplicate values in the newly created array and return their keys */
$dubs = get_keys_for_duplicate_values($userids);

/* Unset all the duplicate keys from the original array */
foreach($dubs as $key){
    unset($result[$key]);
}

/* Re-arrange the original array keys */
$result = array_values($result);

echo '<pre>';
print_r($result);
echo '</pre>';

?>

函数取自这个问题的答案:Get the keys for duplicate values in an array

输出:

Array
(
    [0] => Array
        (
            [user_id] => 82
            [ac_type] => 1
        )

    [1] => Array
        (
            [user_id] => 80
            [ac_type] => 5
        )

    [2] => Array
        (
            [user_id] => 76
            [ac_type] => 1
        )

)

【讨论】:

    【解决方案2】:

    经过测试和工作的示例。

    <?php 
    
    $details = array('0'=> array('user_id'=>'82', 'ac_type'=>'1'), '1'=> array('user_id'=>'80', 'ac_type'=>'5'), '2'=>array('user_id'=>'76', 'ac_type'=>'1'), '3'=>array('user_id'=>'82', 'ac_type'=>'1'), '4'=>array('user_id'=>'80', 'ac_type'=>'5'));
    
    function unique_multidim_array($array, $key) { 
    $temp_array = array(); 
    $i = 0; 
    $key_array = array(); 
    
    foreach($array as $val) { 
        if (!in_array($val[$key], $key_array)) { 
            $key_array[$i] = $val[$key]; 
            $temp_array[$i] = $val; 
        } 
        $i++; 
        } 
      return $temp_array; 
     } 
    ?> 
    
    <?php 
    $details = unique_multidim_array($details,'user_id'); 
    ?> 
    
     <pre>
    
     <?php print_r($details); ?>
    
    </pre> 
    

    将输出:

    Array
    (
    [0] => Array
        (
            [user_id] => 82
            [ac_type] => 1
        )
    
    [1] => Array
        (
            [user_id] => 80
            [ac_type] => 5
        )
    
    [2] => Array
        (
            [user_id] => 76
            [ac_type] => 1
        )
    )
    

    取自这里http://php.net/manual/en/function.array-unique.php在用户贡献的笔记中。

    【讨论】:

      【解决方案3】:

      此任务不需要任何自定义函数调用。只需使用array_column() 为每个子数组分配新的临时键,然后重新索引子数组并打印到屏幕上。 *这确实会用较晚的事件覆盖较早的事件。

      代码:(Demo)

      $array=[
          ['user_id'=>82,'ac_type'=>1],
          ['user_id'=>80,'ac_type'=>5],
          ['user_id'=>76,'ac_type'=>1],
          ['user_id'=>82,'ac_type'=>2],
          ['user_id'=>80,'ac_type'=>6]
      ];
      var_export(array_values(array_column($array,NULL,'user_id')));
      

      输出:

      array (
        0 => 
        array (
          'user_id' => 82,
          'ac_type' => 2,
        ),
        1 => 
        array (
          'user_id' => 80,
          'ac_type' => 6,
        ),
        2 => 
        array (
          'user_id' => 76,
          'ac_type' => 1,
        ),
      )
      

      如果您想保留第一次出现并忽略所有后续重复项,则可以这样做:

      代码:(Demo)(* 保留第一次出现)

      $array=[
          ['user_id'=>82,'ac_type'=>1],
          ['user_id'=>80,'ac_type'=>5],
          ['user_id'=>76,'ac_type'=>1],
          ['user_id'=>82,'ac_type'=>2],
          ['user_id'=>80,'ac_type'=>6]
      ];
      
      foreach($array as $a){
          if(!isset($result[$a['user_id']])){
              $result[$a['user_id']]=$a;      // only store first occurence of user_id
          }
      }
      var_export(array_values($result));  // re-index
      

      输出:

      array (
        0 => 
        array (
          'user_id' => 82,
          'ac_type' => 1,
        ),
        1 => 
        array (
          'user_id' => 80,
          'ac_type' => 5,
        ),
        2 => 
        array (
          'user_id' => 76,
          'ac_type' => 1,
        ),
      )
      

      如果您不介意丢失子数组的顺序,可以使用 array_reverse()array_column() 使用临时键保留第一次出现,然后使用 array_values() 重新索引:

      var_export(array_values(array_column(array_reverse($array),NULL,'user_id')));
      /*
      array (
        0 => 
        array (
          'user_id' => 76,
          'ac_type' => 1,
        ),
        1 => 
        array (
          'user_id' => 82,
          'ac_type' => 1,
        ),
        2 => 
        array (
          'user_id' => 80,
          'ac_type' => 5,
        ),
      )
      */
      

      【讨论】:

      • 我不确定这是否是他想要的。他只想删除基于 user_id 的重复项。这将保留 last 副本并删除所有以前的副本。我认为他想保留第一个匹配项并在之后删除所有重复项?
      • 你是对的。如果这对实际应用程序有影响,我需要对其进行重新设计以保留第一次出现的情况。
      • 无论如何,我要 +1。我实际上从你的回答中学到了一些东西。谢谢:)
      • 感谢您的回答。
      • 不错!很有用! +1。
      【解决方案4】:
      $array = [
          ['user_id'=>82,'ac_type'=>1],
          ['user_id'=>80,'ac_type'=>5],
          ['user_id'=>76,'ac_type'=>1],
          ['user_id'=>82,'ac_type'=>2],
          ['user_id'=>80,'ac_type'=>6]
      ];
      
      $array = array_reverse($array);
      
      $v = array_reverse( 
          array_values( 
              array_combine( 
                  array_column($array, 'user_id'),
                  $array
              )
          )
      );
      
      
      echo '<pre>';
      var_dump($v);
      

      结果:

      array(3) {
        [0]=>
        array(2) {
          ["user_id"]=>
          int(76)
          ["ac_type"]=>
          int(1)
        }
        [1]=>
        array(2) {
          ["user_id"]=>
          int(82)
          ["ac_type"]=>
          int(1)
        }
        [2]=>
        array(2) {
          ["user_id"]=>
          int(80)
          ["ac_type"]=>
          int(5)
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-04-05
        • 2017-06-01
        • 1970-01-01
        • 2018-09-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多