2009-09-11 3 views
1

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

Вот как выглядит массив. Первые два заказа - это дубликаты заказов по ошибке. Вы заметите, что порядок заказа для каждого отличается, тогда как адрес электронной почты и идентификатор пользователя остаются прежними. Таким образом, дублирование должно соответствовать по электронной почте и/или идентификатору пользователя, но не по заказу.

array 
    0 => 
    array 
     'orderid' => string '2009091008261662' 
     'email' => string '[email protected]' 
     'userid' => string '53' 
array 
    1 => 
    array 
     'orderid' => string '2009091008261048' 
     'email' => string '[email protected]' 
     'userid' => string '53' 
array 
    2 => 
    array 
     'orderid' => string '2009091008262025' 
     'email' => string '[email protected]' 
     'userid' => string '103' 
array 
    3 => 
    array 
     'orderid' => string '2009091008272082' 
     'email' => string '[email protected]' 
     'userid' => string '392' 

Как я могу искать дубликаты заказов от одного и того же человека в заданном массиве на PHP?

Я хотел бы выход выше примерно так:

(ITS делают вид в таблице)

2009091008261662 - [email protected] - 53

2009091008261048 - Джон @ пример .com - 53

2009091008262025 - [email protected] - 103

2009091008272082 - [email protected] - 392

... так что в основном просто выделите два (или более) дубликата.

ответ

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; 
    } 
} 
-1

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

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

-1 для O (n^2), когда это может быть только O (2n) -> O (n). Кроме того, вы можете просто вернуть true, как только $ count не будет 0 вместо итерации всего массива. –

+0

Я сказал, что это просто неэффективно. Остерегайтесь преждевременной оптимизации. И да, вы можете вернуть true, как только $ count> 1. Но не 0, так как всегда будет 1 матч. – Craig

4

Предполагает уникальность основана на userid Значение

<?php 

$orders = array(
    array(
    'orderid' => '2009091008261662', 
    'email' => '[email protected]', 
    'userid' => '53' 
), 
    array(
    'orderid' => '2009091008261048', 
    'email' => '[email protected]', 
    'userid' => '53' 
), 
    array(
    'orderid' => '2009091008262025', 
    'email' => '[email protected]', 
    'userid' => '103' 
), 
    array(
    'orderid' => '2009091008272082', 
    'email' => '[email protected]', 
    'userid' => '392' 
), 
    array(
    'orderid' => '2009091008265555', 
    'email' => '[email protected]', 
    '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> 
+0

haha ​​funny, я придумал ту же основную концепцию. – Dooltaz

0

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

0

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

$array1[0]['orderid'] = '2009091008261662'; 
$array1[0]['email'] = '[email protected]'; 
$array1[0]['userid'] = '53'; 
$array1[1]['orderid'] = '2009091008261662'; 
$array1[1]['email'] = '[email protected]'; 
$array1[1]['userid'] = '53'; 
$array1[2]['orderid'] = '2009091008261662'; 
$array1[2]['email'] = '[email protected]'; 
$array1[2]['userid'] = '53'; 
$array1[3]['orderid'] = '209091008261662'; 
$array1[3]['email'] = '[email protected]'; 
$array1[3]['userid'] = '53'; 
$array1[4]['orderid'] = '2001008261662'; 
$array1[4]['email'] = '[email protected]'; 
$array1[4]['userid'] = '53'; 
$array1[5]['orderid'] = '20013344008261662'; 
$array1[5]['email'] = '[email protected]'; 
$array1[5]['userid'] = '53'; 
$array1[6]['orderid'] = '200133352008261662'; 
$array1[6]['email'] = '[email protected]'; 
$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

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

$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 = array(
    array(
    'orderid' => '2009091008261662', 
    'email' => '[email protected]', 
    'userid' => '53' 
), 
    array(
    'orderid' => '2009091008261048', 
    'email' => '[email protected]', 
    'userid' => '53' 
), 
    array(
    'orderid' => '2009091008262025', 
    'email' => '[email protected]', 
    'userid' => '103' 
), 
    array(
    'orderid' => '2009091008272082', 
    'email' => '[email protected]', 
    'userid' => '392' 
), 
    array(
    'orderid' => '2009091008265555', 
    'email' => '[email protected]', 
    'userid' => '53' 
) 
); 

Кроме того, это может быть лучше соответствовать только на USERID так, по-видимому, пользователи могут изменять свои электронные письма, а электронные письма уникальны для одного пользователя.

 Смежные вопросы

  • Нет связанных вопросов^_^