Find all array keys that has same value
Solution 1
Taking advantage of closures for a more straightforward solution:
$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);
This gave me the following:
array(2) {
["a"]=>
int(1000)
["c"]=>
int(1000)
}
Demo: https://eval.in/67526
That's all! :)
Update: backward-compatible solution
$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);
Demo: https://eval.in/68255
Solution 2
Your implementation has a few issues.
1) If there are 2 of value 1000 and 2 of another value, the array_flip will lose one of the sets of values.
2) If there are more than two different values, the array_keys will only find the one value that occurs most.
3) If there are no duplicates, you will still bring back one of the values.
Something like this works always and will return all duplicate values:
<?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);
http://codepad.viper-7.com/fal5Yz
Solution 3
at the moment I cant figure out another solution...
// 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));
output:
Array
(
[0] => Array
(
[a] => 1000
[c] => 1000
)
)
example #2: - when you have different values multiplied
// target array
$your_array = array('a'=>1000, 'b'=>1, 'c'=>1000, 'd'=>500, 'e'=>1);
// output
print_r(get_duplicate_elements($your_array));
output:
Array
(
[0] => Array
(
[a] => 1000
[c] => 1000
)
[1] => Array
(
[b] => 1
[e] => 1
)
)
if function result has been assigned to $res
variable $res[0]
gets an array of all elements from original array with first value found more than once, $res[1]
gets array of elements with another duplicated-value, etc... function returns false
if nothing duplicate has been found in argument-array.
Solution 4
If you want to get the duplicates in an array try this:
array_unique(array_diff_assoc($array1, array_unique($array1)))
I found this from:
http://www.php.net/manual/en/function.array-unique.php#95203
Solution 5
Try this
$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);
micadelli
Updated on June 04, 2022Comments
-
micadelli almost 2 years
Is there a simpler way to get all array keys that has same value, when the value is unknown.
The problem with
array_unique
is that it returns the unique array and thus it doesn't find unique values.That is, for example, from this array:
Array ( [a]=>1000 [b]=>1 [c]=>1000 )
I want to get this
Array ( [a]=>1000 [c]=>1000 )
Another way around this is, if I could find the lonely values, and then their keys, and then use
array_diff
This is what I've got so far, looks awful:
$a = array( 'a' => 1000, 'b' => 1, 'c' => 1000 ); $b = array_flip( array_count_values( $a ) ); krsort( $b ); $final = array_keys( $a, array_shift( $b ) );
Update
Using Paulo Freites' answer as a code base, I could get it working pretty easily, maintainable and easy on eyes kind of way… by using the filtering as a static class method I can get the duplicate values from an array by just callingClassName::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' ); }
-
micadelli over 10 yearsthat method returns the key/value that has the duplicates itself
-
micadelli over 10 yearsupdated… i don't know the value. the value is "duplicate value"
-
Wh1T3h4Ck5 over 10 yearsah, you want to match duplicate values first then to pull elements out.
-
SamV over 10 yearsAh, okay misunderstanding.
-
micadelli over 10 yearscorrect… that's what my script does, but i thought it could be achieved way more simpler
-
SamV over 10 years@micadelli I found a nice little snippet from the comments section below in the
array_unique
php docs, hope that helps. -
Wh1T3h4Ck5 over 10 yearsit now works, even if you have more different values duplicated in an array.
-
micadelli over 10 yearssorry, dude, didn't mention that those values are random, only put 1 vs 1000 for readability
-
micadelli over 10 yearsnice one. Isn't this working only in PHP 5.3 and above? The server has 5.2.4
-
user222758 over 10 years@micadelli Unfortunately yes! I've updated my answer with a backward-compatible solution which uses
create_function()
in place of closures. :) -
micadelli over 10 yearsinteresting stuff, that
create_function
. Unfortunately thought, it has bad performance and memory usage characteristics… Somehow coming from JavaScript side, I like to stay away from any evileval
kind of code :) I'll try to fork your code using a static class method instead and see how it works. -
user222758 over 10 years@micadelli Yea,
create_function()
it's not so bad, but have disadvantages in place of closures... You can get more info about that difference here: stackoverflow.com/q/6485336/222758 Unfortunately, the only other way to achieve that witharray_filter()
is the way you've switched for, using classes. It's not so bad either... Glad to know that I was able to help you! :) -
abfurlan over 10 yearsI edited the code, sorry. See if it works for you. @micadelli