php 从二维数组中删除重复行,但保留特定列中具有非空值的行

oipij1gg  于 2023-01-24  发布在  PHP
关注(0)|答案(7)|浏览(116)

我有一个二维数组,其中包含可能多次表示用户的行。我需要删除用户数据的重复示例,但不希望在此过程中丢失任何有意义的数据。Flying Tour列中具有非空值的行应优先于同一列中具有空值的行。
样本数据:

$data = [
    [
        'Access ID' => 12345,
        'Registration Date' => '2018-02-27',
        'First Name' => 'Damian',
        'Last Name' => 'Martin',
        'Flying Tour' => ''
    ],
    [
        'Access ID' => 12345,
        'Registration Date' => '2018-02-27',
        'First Name' => 'Damian',
        'Last Name' => 'Martin',
        'Flying Tour' => 'Yes going'
    ],
    [
        'Access ID' => 789456,
        'Registration Date' => '2018-03-27',
        'First Name' => 'Ricky',
        'Last Name' => 'Smith',
        'Flying Tour' => ''
    ],
    [
        'Access ID' => 789456,
        'Registration Date' => '2018-03-27',
        'First Name' => 'Ricky',
        'Last Name' => 'Smith',
        'Flying Tour' => 'Two way going',
    ],
    [
        'Access ID' => 987654,
        'Registration Date' => '2018-04-27',
        'First Name' => 'Darron',
        'Last Name' => 'Butt',
        'Flying Tour' => ''
    ]
];

我的代码:

$results = [];
      foreach($data as $input){

      $isDuplicate = false;
      foreach($results as $result){
        if(
            strtolower($input['First Name'])===strtolower($result['First Name']) &&
            strtolower($input['Last Name'])===strtolower($result['Last Name'])      &&
            strtolower($input['Registration ID'])===strtolower($result['Registration ID']) &&
            strtolower(!empty($input['Flying Tour']))
        ){
            //a duplicate was found in results
            $isDuplicate = true;
            break;
        }
      }
      //if no duplicate was found
      if(!$isDuplicate) $results[]=$input;
}

预期结果:

Array
(
    [0] => Array
        (
            [Access ID] => 12345
            [Registration Date] => 2018-02-27
            [First Name] => Damian
            [Last Name] => Martin
            [Flying Tour] => Yes going
        )

    [1] => Array
        (
            [Access ID] => 789456
            [Registration Date] => 2018-03-27
            [First Name] => Ricky
            [Last Name] => Smith
            [Flying Tour] => Two way going
        )

    [2] => Array
        (
            [Access ID] => 987654
            [Registration Date] => 2018-04-27
            [First Name] => Darron
            [Last Name] => Butt
            [Flying Tour] => 
        )

)

进行了一些更改,请参见

kmpatx3s

kmpatx3s1#

使用foreach()和数组键检查重复项:

$results = [];
foreach ($data as $input) {
    if (!isset($results[$input['Access ID'] . '_' . $input['First Name'] . '_' . $input['Last Name']])) {
            $results[$input['Access ID'] . '_' . $input['First Name'] . '_' . $input['Last Name']] = $input;
    } else {
        if ($results[$input['Access ID'] . '_' . $input['First Name'] . '_' . $input['Last Name']]['Flying Tour'] == '') {
            $results[$input['Access ID'] . '_' . $input['First Name'] . '_' . $input['Last Name']] = $input;
        }
    }
}

$results = array_values($results);
//array_multisort( array_column($results, "First Name"), SORT_ASC, $results );
echo "<pre/>";
print_r($results);

样本输出:https://3v4l.org/2KcSN

93ze6v8z

93ze6v8z2#

使用foreach迭代$data。通过$duplicates变量存储重复信息,并使用它删除重复值。

备选案文:

$duplicates = array();
$results = $data;

foreach( $results as $k=>$v ) {
    if( isset( $duplicates[$v['Access ID']] ) ) {
        unset( $results[$k] );
    }
    else $duplicates[$v['Access ID']] = TRUE;
}

print_r( $results );
ffdz8vbo

ffdz8vbo3#

从应该是唯一的值组成键。
如果$results中不存在来自每个循环数组的组合键,则将其包含在结果中。
此外,如果组合键存在且Flying Tour值为空,则替换为新数组。

$results = [];

foreach ($data as $input) {
    $key = implode([
        $input['First Name'], 
        $input['Last Name'], 
        $input['Access ID']
    ], '-');

    if (array_key_exists($key, $results) 
        && !empty($results[$key]['Flying Tour'])) continue;

    $results[$key] = $input;
}

var_dump(array_values($results));
wfsdck30

wfsdck304#

这里的要点是,在第一次运行时,$results仍然是空的,因此,可以设置$isDuplicate = true的整个逻辑永远不会在第一个示例中运行。
这意味着对于第一个记录,$isDuplicate = false,因此它将始终被添加。
此外,X1 M3 N1 X有点奇怪...在我看来应该给予一个错误(即使它没有...)
你应该把!empty($input['Flying Tour'])移到for循环之外,因为它不需要新数组中的当前值来进行检查,这样就可以解决问题。

if(!$isDuplicate && !empty($input['Flying Tour'])) $results[]=$input;

如果你想学习和改进你的代码,看看array_filter它是为这个目的:滤波阵列结果。
--编辑

foreach($results as $id => $result){
    if(
        strtolower($input['First Name'])===strtolower($result['First Name']) &&
        strtolower($input['Last Name'])===strtolower($result['Last Name'])      &&
        strtolower($input['Registration ID'])===strtolower($result['Registration ID']))
    ){
        // Check if the $results value for Flying Tour is empty
        // if yes: update its value $results[ $id ]['Flying Tour'] = $input['Flying Tour'], but still mark as duplicate(!)

        //a duplicate was found in results
        $isDuplicate = true;
        break;
    }
  }
yqyhoc1h

yqyhoc1h5#

要按唯一用户分组,您只需引用其唯一访问编号。使用该值作为结果数组中的分组第一级关键字。在迭代时,如果访问ID没有保存的行,则保存该行。如果该行存在,但Flying Tour值为空,则将当前行保存在其位置。完成迭代后,可以通过调用array_values()来删除关联的第一级键。
代码:(Demo

$result = [];
foreach ($data as $row) {
    if (empty($result[$row['Access ID']]['Flying Tour'])) {
        $result[$row['Access ID']] = $row;
    }
}
var_export(array_values($result));
xwbd5t1u

xwbd5t1u6#

$arrayvalues = array();   // Set the array before foreach 
foreach( $res as $key=>$value ) {
    if( isset( $arrayvalues[$value['Access ID']] ) ) {   // Here checking the Array value and $value are same
        unset( $res[$key] );            // unset the array key value here
    }
    else $arrayvalues[$value['Access ID']] = $value['Access ID'];      // If it is not it will display here and returns true.
}

$i=0;
$testvalues = array();   // Set the array before foreach 
foreach ($res as $key => $value) {
    print_r($value);
    $arr[$i] = $value;
    $testvalues[$i]=$arr[$i];

    // unset($arr[$key]);
    $i++;
}

echo "<pre>";
print_r($testvalues) ;   // Get the respective out put here
echo "</pre>";
4smxwvx5

4smxwvx57#

echo '<pre>';
$data = array_reverse($data);
$combined = array_map(function($row){

    $row = array_map('trim', $row);
    unset($row['Flying Tour']);
    //print_r($row);exit;
    return array_reduce($row, function($v1,$v2){
        return $v1 . "|" . $v2;
    });
}, $data);

$uniqueElements  = array_unique($combined);

$uniqueIndexes = array_keys($uniqueElements);
$newData = [];

foreach ($data as $key => $value) {
    if(in_array($key, $uniqueIndexes)){
        $newData[] = $value;
    }
}

print_r($newData);

相关问题