Выделить повторяющиеся значения в многомерном массиве - PullRequest
1 голос
/ 12 сентября 2009

Я выводлю список покупок и хочу автоматически выделить наличие дублирующих заказов.

Вот как выглядит массив. Первые два заказа являются дубликатами, размещенными по ошибке. Вы заметите, что orderid для каждого из них различен, а адрес электронной почты и идентификатор пользователя остаются неизменными. Поэтому дублирование должно совпадать по электронной почте и / или идентификатору пользователя, но не по 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 ]

4 голосов
/ 12 сентября 2009

Принимает уникальность на основе 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 голос
/ 12 сентября 2009

Ваша лучшая ставка будет по существу "инвертировать" массив в ассоциативное сопоставление значений ключам из исходного массива:

$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;
    }
}
0 голосов
/ 12 сентября 2009

Вам понадобится два прохода массива заказов. Но это действительно проще, чем некоторые думают:

$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, поскольку, предположительно, пользователи могут изменять свои электронные письма, а электронные письма уникальны для одного пользователя.

0 голосов
/ 12 сентября 2009

Этот код работает ...

$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";
 }
}
0 голосов
/ 12 сентября 2009

Вы можете добавить хеш к внутреннему массиву, который представляет массив. Просто переберите и сравните хэши.

0 голосов
/ 12 сентября 2009

Простой ответ:

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