2009-08-11 3 views
18

Я хочу получить все дублированные записи из массива. Возможно ли это в PHP?php возвращает только дублированные записи из массива

array(
    1 => '1233', 
    2 => '12334', 
    3 => 'Hello', 
    4 => 'hello', 
    5 => 'U' 
); 

Я хочу вернуть массив только с удвоенным значением: «привет».

Желаемая выходной массив:

array(
    1 => 'Hello', 
    2 => 'hello' 
); 
+0

Существует аналогичный вопрос: http: // stackoverflow.com/questions/1212605/php-array-search-for-multiple-values ​​/ 1212863 –

ответ

16

You нужно будет сделать ваши функции чувствительны к регистру, чтобы получить "Hello" => "привет" результат вы ищете, попробуйте этот метод:

$arr = array(1=>'1233',2=>'12334',3 =>'Hello' ,4=>'hello', 5=>'U'); 

// Convert every value to uppercase, and remove duplicate values 
$withoutDuplicates = array_unique(array_map("strtoupper", $arr)); 

// The difference in the original array, and the $withoutDuplicates array 
// will be the duplicate values 
$duplicates = array_diff($arr, $withoutDuplicates); 
print_r($duplicates); 

Выход:

Array 
(
[3] => Hello 
[4] => hello 
) 

Редактировать by @AlixAxel:

Этот ответ очень вводит в заблуждение. Он работает только в этом конкретном состоянии. Этот счетчик-пример:

$arr = array(1=>'1233',2=>'12334',3 =>'Hello' ,4=>'HELLO', 5=>'U'); 

Fails miserably. Кроме того, это не способ держать дубликаты:

array_diff($arr, array_unique($arr)); 

Поскольку одной из дублированных значений будет array_unique, а затем отрубил array_diff.

Редактируйте @RyanDay:

Так что смотрите на @ Srikanth-х или @ ответ Bucabay, который работа для всех случаев (искать случае нечувствительной в Bucabay-х), а не только тестовые данные, указанные в этом вопросе.

+0

Очень чистый и приятный способ сделать это. Добавьте к нему некоторые комментарии, чтобы понять, как могут программисты PHP-кодов noob: можно написать какой-то аккуратный код с этим языком, и это должно быть известно :-) –

+0

Кстати, если массив очень длинный, я рекомендую иметь пример с использованием итератора шаблон SPL для сохранения памяти. –

+0

Вам понадобится array_diff_key(), иначе вы вернете каждое значение, которое не является прописным в исходном массиве. – bucabay

2

Try:

$arr2 = array_diff_key($arr, array_unique($arr)); 

регистронезависимы:

array_diff_key($arr, array_unique(array_map('strtolower', $arr))); 
+0

хорошее и короткое решение. – powtac

+1

-1, Одно из дублированных значений будет удалено, не возвратит все дубликаты. –

20
<?php 
function array_not_unique($raw_array) { 
    $dupes = array(); 
    natcasesort($raw_array); 
    reset($raw_array); 

    $old_key = NULL; 
    $old_value = NULL; 
    foreach ($raw_array as $key => $value) { 
     if ($value === NULL) { continue; } 
     if (strcasecmp($old_value, $value) === 0) { 
      $dupes[$old_key] = $old_value; 
      $dupes[$key]  = $value; 
     } 
     $old_value = $value; 
     $old_key = $key; 
    } 
    return $dupes; 
} 

$raw_array = array(); 
$raw_array[1] = '[email protected]yz.com'; 
$raw_array[2] = '[email protected]'; 
$raw_array[3] = '[email protected]'; 
$raw_array[4] = '[email protected]'; // Duplicate 

$common_stuff = array_not_unique($raw_array); 
var_dump($common_stuff); 
+0

очень умное решение! – bucabay

+0

Yup, хорошее решение (оно работает)! –

+0

отличный ответ, спасибо –

5
function array_not_unique($raw_array) { 
    $dupes = array(); 
    natcasesort($raw_array); 
    reset($raw_array); 

    $old_key = NULL; 
    $old_value = NULL; 
    foreach ($raw_array as $key => $value) { 
     if ($value === NULL) { continue; } 
     if (strcasecmp($old_value, $value) === 0) { 
      $dupes[$old_key] = $old_value; 
      $dupes[$key]  = $value; 
     } 
     $old_value = $value; 
     $old_key = $key; 
    } return $dupes; 
} 

Что Srikanth (джон) добавил, но со случаем нечувствительным сравнения.

+0

спасибо хороший! –

4

Это правильный способ сделать это (чувствителен к регистру):

array_intersect($arr, array_unique(array_diff_key($arr, array_unique($arr)))); 

И регистронезависимым решение:

$iArr = array_map('strtolower', $arr); 
$iArr = array_intersect($iArr, array_unique(array_diff_key($iArr, array_unique($iArr)))); 

array_intersect_key($arr, $iArr); 

Но @Srikanth ответ является более эффективным (на самом деле, это только тот, который работает правильно кроме этого этот).

+0

Хорошо, я буду кусать. Мое решение имеет ошибку, но ваш не дает возвращаемого значения, которое ищет OP. Я не понимаю, как мой ответ - несчастный провал, а ваш лучше? – ryanday

+0

@ryanday: Моя работа делает это с учётом чувствительности к регистру и может быть адаптирована для учета нечувствительности к регистру. С другой стороны, ваш ответ почти так же полезен, как 'return array (1 => 'Hello', 2 => 'hello');'. Надеюсь, вы получите мою точку зрения ... –

+0

@ryanday: Добавлена ​​версия без учета регистра. –

10
function get_duplicates ($array) { 
    return array_unique(array_diff_assoc($array, array_unique($array))); 
} 
Смежные вопросы