突出显示多维数组中的重复值

时间:2009-09-11 22:29:37

标签: php multidimensional-array duplicate-data

我正在输出购买清单,我想自动突出显示重复订单的存在。

这是阵列的样子。前两个订单是错误的重复订单。您会注意到每个的orderid不同,而email和userid保持不变。因此,复制需要在电子邮件和/或用户ID上匹配,而不是在orderid上匹配。

array
  0 => 
    array
      'orderid' => string '2009091008261662'
      'email' => string 'john@example.com'
      'userid' => string '53'
array
  1 => 
    array
      'orderid' => string '2009091008261048'
      'email' => string 'john@example.com'
      'userid' => string '53'
array
  2 => 
    array
      'orderid' => string '2009091008262025'
      'email' => string 'fred@example.com'
      'userid' => string '103'
array
  3 => 
    array
      'orderid' => string '2009091008272082'
      'email' => string 'tom@example.com'
      'userid' => string '392'

如何在PHP中搜索给定数组中同一个人的重复订单?

我想输出以上内容:

(假装在桌子上)

2009091008261662 - john@example.com - 53

2009091008261048 - john@example.com - 53

2009091008262025 - fred@example.com - 103

2009091008272082 - tom@example.com - 392

...所以基本上只是突出显示两个(或更多)副本。

6 个答案:

答案 0 :(得分:4)

根据userid

假设唯一性
<?php

$orders = array(
  array(
    'orderid' => '2009091008261662',
    'email' => 'john@example.com',
    'userid' => '53'
  ),
  array(
    'orderid' => '2009091008261048',
    'email' => 'john@example.com',
    'userid' => '53'
  ),
  array(
    'orderid' => '2009091008262025',
    'email' => 'fred@example.com',
    'userid' => '103'
  ),
  array(
    'orderid' => '2009091008272082',
    'email' => 'tom@example.com',
    'userid' => '392'
  ),
  array(
    'orderid' => '2009091008265555',
    'email' => 'john@example.com',
    'userid' => '53'
  )
);

$foundIds = array();
foreach ( $orders as $index => $order )
{
  if ( isset( $foundIds[$order['userid']] ) )
  {
    $orders[$index]['is_dupe'] = true;
    $orders[$foundIds[$order['userid']]]['is_dupe'] = true;
  } else {
    $orders[$index]['is_dupe'] = false;
  }
  $foundIds[$order['userid']] = $index;
}
?>

<style type="text/css">
tr.dupe td {
  font-weight: bold;
}
</style>

<table>
  <tr><th>orderid</th><th>email</th><th>
  <?php foreach ( $orders as $order ) { ?>
  <tr class="<?php echo $order['is_dupe'] ? 'dupe' : '' ?>">
    <td><?php echo $order['orderid']; ?></td>
    <td><?php echo $order['email']; ?></td>
    <td><?php echo $order['userid']; ?></td>
  </tr>
  <?php } ?>
</table>

答案 1 :(得分:1)

你最好的选择是将数组“反转”为一个关联的数组,将值映射到原始数组中的键:

$emails = array();
$userids = array();

foreach($inputarray as $key => $item) {
    if( isset($emails[$item['email']]) || isset($userids[$item['userid']]) ) {
        // This item has a duplicate email or userid as something already looked at!
        // $emails[$item['email']] or $userids[$item['userid']] has the key corresponding to the original location where it was seen.
        // $key has the key corresponding to the duplicate we just found.
    } else {
        $emails[$item['email']] = $key;
        $userids[$item['userid']] = $key;
    }
}

答案 2 :(得分:0)

您可以向表示数组的内部数组添加哈希值。只需循环并比较哈希值。

答案 3 :(得分:0)

此代码有效......

$array1[0]['orderid'] = '2009091008261662';
$array1[0]['email'] = 'john@example.com';
$array1[0]['userid'] = '53';
$array1[1]['orderid'] = '2009091008261662';
$array1[1]['email'] = 'john@example.com';
$array1[1]['userid'] = '53';
$array1[2]['orderid'] = '2009091008261662';
$array1[2]['email'] = 'john2@example.com';
$array1[2]['userid'] = '53';
$array1[3]['orderid'] = '209091008261662';
$array1[3]['email'] = 'joh3@example.com';
$array1[3]['userid'] = '53';
$array1[4]['orderid'] = '2001008261662';
$array1[4]['email'] = 'john@example.com';
$array1[4]['userid'] = '53';
$array1[5]['orderid'] = '20013344008261662';
$array1[5]['email'] = 'johnddd@example.com';
$array1[5]['userid'] = '53';
$array1[6]['orderid'] = '200133352008261662';
$array1[6]['email'] = 'johsdfgsdn@example.com';
$array1[6]['userid'] = '53';


$unique_array = array(); // Filtered array with no dupes
$email_array = array(); // Hash list
$order_array = array(); // Hash list
foreach($array1 as $i => $row) {

 if (array_key_exists($row['email'], $email_array)) {
  // This is a dupe based on email
  $array1[$i]['duplicate'] = 1;
  $array1[$email_array[$row['email']]]['duplicate'] = 1;
 }

 if (array_key_exists($row['orderid'], $order_array)) {
  // This is a dupe based on email
  $array1[$i]['duplicate'] = 1;
  $array1[$order_array[$row['orderid']]]['duplicate'] = 1;
 }
 $order_array[$row['orderid']] = $i;
 $email_array[$row['email']] = $i;
}
foreach($array1 as $i => $row) {
 if (!empty($row['duplicate'])) {
  echo "<b>" . $row['orderid'] . $row['email'] . "</b>\n";
  unset($row['duplicate']); // reset the array to original form
 } else {
  echo $row['orderid'] . $row['email'] . "\n";
 }
}

答案 4 :(得分:0)

你需要两次传递orders数组。但它确实比一些人做得更简单:

$duplicateUserId = array();

// Mark user ID's with more than one order
foreach ( $orders as $order ) {
    $duplicateUserId[$order['userid']] = isset($duplicateUserId[$order['userid']]);
}

// Output each order
foreach ( $orders as $order ) {
    echo formatOrder($order, $duplicateUserId[$order['userid']]);
}

// Format the output of each order
function formatOrder($order, $isDuplicated) {
    // yadda yadda yadda
}

假设$ orders看起来像

$orders = array(
  array(
    'orderid' => '2009091008261662',
    'email' => 'john@example.com',
    'userid' => '53'
  ),
  array(
    'orderid' => '2009091008261048',
    'email' => 'john@example.com',
    'userid' => '53'
  ),
  array(
    'orderid' => '2009091008262025',
    'email' => 'fred@example.com',
    'userid' => '103'
  ),
  array(
    'orderid' => '2009091008272082',
    'email' => 'tom@example.com',
    'userid' => '392'
  ),
  array(
    'orderid' => '2009091008265555',
    'email' => 'john@example.com',
    'userid' => '53'
  )
);

此外,最好只匹配userId,因为用户可以更改他们的电子邮件和电子邮件对于单个用户来说是唯一的。

答案 5 :(得分:-1)

简单回答:

function hasDuplicate($arr,$email) {
  $count = 0;
  foreach ($arr as $row) {
     if ($row['email'] == $email) {
       $count++;
     }
  }
  return ($count >1);
}