PHP - 确保多维数组中的某些值是唯一的

时间:2016-08-04 09:35:59

标签: php arrays multidimensional-array

我有一个多维数组。 这里只有两个记录的示例,但可能还有更多:

array(2) {
[0]=> array(7)
{
[0]=> string(0) ""
[1]=> string(0) ""
[2]=> string(7) "4646468"
[3]=> string(1) "1"
[4]=> string(1) "2"
[5]=> string(10) "2016-08-18"
[6]=> string(0) ""
}
[1]=> array(7)
{
[0]=> string(0) ""
[1]=> string(0) ""
[2]=> string(7) "4646469"
[3]=> string(1) "1"
[4]=> string(1) "2"
[5]=> string(10) "2016-08-18"
[6]=> string(0) ""
}
}

我需要确保每个内部记录的键0,1和2的值是唯一的。如果其中任何一个不是,我想从数组中删除该记录(如,具有其7值的数组元素)(但是应该忽略空字符串)。我发现this answer to a similar question成功地为我输出了重复项,但我也想从主数组中删除它们。问题是我根本不懂代码。我不理解回调,因此不知道如何修改此代码以实现我的需求:

$unique = array();
foreach($checked as $v) {
    $key = $v[0] . $v[1] . $v[2];
    if (!isset($unique[$key]))
        $unique[$key] = 0;
    else
        $unique[$key]++;
}
print_r(array_filter($unique));

3 个答案:

答案 0 :(得分:0)

您可以执行此操作,修改您添加的初始代码段:

//$main_array contains your original array data.

$unique = array();

foreach($main_array as $key=>$value) {
    $key_combination = $value[0] . '-' . $value[1] . '-'. $value[2];
    //add the key combination to array if it doesn't initially exists
    if (!isset($unique[$key_combination])){
        $unique[$key_combination] = 0;
       }
    //if it gets to this condition means this key combination is a 
    //duplicate and we need to remove the element from main_array
    else{
        unset($main_array[$key]);
       }
}

print_r($main_array);//should contain your original array with duplicates removed

让我们试试这条路线

$unique = array();
foreach($main_array as $key=>$value) {
    $key_combination = $value[0] . '-'.  $value[1] . '-'. $value[2];
    //add the key combination to array if it doesn't initially exists
    if (!in_array($key_combination, $unique)){  //This is the change
        $unique[] = $key_combination;// track duplicates by storing in array
       }
    //if it gets to this condition means this key combination is a 
    //duplicate and we need to remove the element from main_array
    else{
        unset($main_array[$key]);
       }
}

答案 1 :(得分:0)

如果你想迭代一个数组并检查“键0,1和2”中的唯一值,在唯一性方面分别处理这些键中的每一个,那么我可能会定义三个数组(哈希),三者各一个,然后执行以下操作:

$exists0 = array(); $exists1 = array(); $exists2 = array);
...
foreach ($array as $record) {
  if (array_key_exists($exists0, $record[0]) ... you have a duplicate.
  $exists0[$record[0]] = true;  // any value will do ...

  if (array_key_exists($exists1, $record[1]) ... etcetera.
}

每个哈希值$exists0, $exists1, $exists2中的键的存在表示该值是重复的。 (在这种情况下,与键... true相关联的值......无关紧要。)

在我的示例中,使用了三个哈希,因为我假设您要分别处理这三个字段。如果你想在三个中的任何中测试dupes,那么对我的例子的改变是微不足道的。显而易见。

答案 2 :(得分:0)

这就是我最终解决的问题:

//make sure either serial, asset tag or hostname have been filled in
foreach($laptops as $num => $laptop){
  if (empty($laptop[0]) && empty ($laptop[1]) && empty($laptop[2])){
    $dont_insert[] = $laptop;
  } else {
    $do_insert[$num] = $laptop;
    if($laptop[0]){$hostnames[$num] = $laptop[0];}
    if($laptop[1]){$asset_tags[$num] = $laptop[1];}
    if($laptop[2]){$serials[$num] = $laptop[2];}
  }
}
//check user hasn't entered the asset tag, serial or hostname more than once
if (count(array_unique($hostnames)) < count($hostnames)) {
  //there are duplicate hostnames
  $counts = array_count_values($hostnames);
  $filtered = array_filter($counts, function($value) {
      return $value != 1;
  });
  $result = array_keys(array_intersect($hostnames, array_keys($filtered)));
  foreach($result as $dupe){
    $dupes[$dupe] = $do_insert[$dupe];
  }
}
if (count(array_unique($asset_tags)) < count($asset_tags)) {
  //there are duplicate asset tags
  $counts = array_count_values($asset_tags);
  $filtered = array_filter($counts, function($value) {
      return $value != 1;
  });
  $result = array_keys(array_intersect($asset_tags, array_keys($filtered)));
  foreach($result as $dupe){
    $dupes[$dupe] = $do_insert[$dupe];
  }
}
if (count(array_unique($serials)) < count($serials)) {
  //there are duplicate serials
  $counts = array_count_values($serials);
  $filtered = array_filter($counts, function($value) {
      return $value != 1;
  });
  $result = array_keys(array_intersect($serials, array_keys($filtered)));
  foreach($result as $dupe){
    $dupes[$dupe] = $do_insert[$dupe];
  }
}
//remove any duplicates from our insertion array
if(count($dupes)){
  foreach($dupes as $num => $dupe){
    unset($do_insert[$num]);
  }
}