Есть ли более простой способ получить все ключи массива с одинаковым значением, когда значение неизвестно.
Проблема с array_unique
заключается в том, что он возвращает уникальный массив и, следовательно, не находит уникальных значений.
То есть, например, из этого массива:
Array ( [a]=>1000 [b]=>1 [c]=>1000 )
Я хочу получить это
Array ( [a]=>1000 [c]=>1000 )
Еще один способ это: если бы я мог найти одинокие значения, а затем их ключи, а затем использовать array_diff
Это то, что у меня есть до сих пор, выглядит ужасно:
$a = array( 'a' => 1000, 'b' => 1, 'c' => 1000 ); $b = array_flip( array_count_values( $a ) ); krsort( $b ); $final = array_keys( $a, array_shift( $b ) );
Обновить
Используя ответ Пауло Фреййтса в качестве базы кода, я мог бы заставить его работать довольно легко, легко и легко на виду … путем использования фильтрации как статического метода класса, я могу получить дубликаты значений из массива, просто вызвав ClassName::get_duplicates($array_to_filter)
private static $counts = null; private static function filter_duplicates ($value) { return self::$counts[ $value ] > 1; } public static function get_duplicates ($array) { self::$counts = array_count_values( $array ); return array_filter( $array, 'ClassName::filter_duplicates' ); }
Воспользовавшись закрытием для более простого решения:
$array = array('a' => 1000, 'b' => 1, 'c' => 1000); $counts = array_count_values($array); $filtered = array_filter($array, function ($value) use ($counts) { return $counts[$value] > 1; }); var_dump($filtered);
Это дало мне следующее:
array(2) { ["a"]=> int(1000) ["c"]=> int(1000) }
Демо: https://eval.in/67526
Это все! 🙂
Обновление: решение с обратной совместимостью
$array = array('a' => 1000, 'b' => 1, 'c' => 1000); $counts = array_count_values($array); $filtered = array_filter($array, create_function('$value', 'global $counts; return $counts[$value] > 1;')); var_dump($filtered);
Демо: https://eval.in/68255
У вашей реализации есть несколько проблем.
1) Если есть 2 значения 1000 и 2 другого значения, array_flip потеряет один из наборов значений.
2) Если имеется более двух разных значений, то array_keys найдет только одно значение, которое больше всего встречается.
3) Если дубликатов нет, вы все равно вернете одно из значений.
Что-то вроде этого работает всегда и вернет все повторяющиеся значения:
<?php //the array $a = array( 'a' => 1000, 'b' => 1, 'c' => 1000 ); //count of values $cnt = array_count_values($a); //a new array $newArray = array(); //loop over existing array foreach($a as $k=>$v){ //if the count for this value is more than 1 (meaning value has a duplicate) if($cnt[$v] > 1){ //add to the new array $newArray[$k] = $v; } } print_r($newArray);
Если вы хотите получить дубликаты в массиве, попробуйте следующее:
array_unique(array_diff_assoc($array1, array_unique($array1)))
Я нашел это от:
http://www.php.net/manual/en/function.array-unique.php#95203
на данный момент я не могу найти другое решение …
// target array $your_array = array('a'=>1000, 'b'=>1, 'c'=>1000); // function to do all the job function get_duplicate_elements($array) { $res = array(); $counts = array_count_values($array); foreach ($counts as $id=>$count) { if ($count > 1) { $r = array(); $keys = array_keys($array, $id); foreach ($keys as $k) $r[$k] = $id; $res[] = $r; } } return sizeof($res) > 0 ? $res : false; } // test it print_r(get_duplicate_elements($your_array));
вывод:
Array ( [0] => Array ( [a] => 1000 [c] => 1000 ) )
пример № 2: – при умножении разных значений
// target array $your_array = array('a'=>1000, 'b'=>1, 'c'=>1000, 'd'=>500, 'e'=>1); // output print_r(get_duplicate_elements($your_array));
вывод:
Array ( [0] => Array ( [a] => 1000 [c] => 1000 ) [1] => Array ( [b] => 1 [e] => 1 ) )
если результат функции присваивается переменной $res[0]
получает массив всех элементов из исходного массива с первым значением, найденным более одного раза, $res[1]
получает массив элементов с другим дублируемым значением и т. д. . функция возвращает false
если в аргументе-массиве не найдено ни одного дубликата.
Попробуй это
$a = array( 'a' => 1, 'b' => 1000, 'c' => 1000,'d'=>'duplicate','e'=>'duplicate','f'=>'ok','g'=>'ok' ); $b = array_map("unserialize", array_unique(array_map("serialize", $a))); $c = array_diff_key($a, $b);