Best solution to remove duplicate values from case-insensitive array [duplicate]
I found a few solutions but I can't decide which one to use. What is the most compact and effective solution to use php's array_unique()
function on a case-insensitive array?
Example:
$input = array('green', 'Green', 'blue', 'yellow', 'blue');
$result = array_unique($input);
print_r($result);
Result:
开发者_开发百科Array ( [0] => green [1] => Green [2] => blue [3] => yellow )
How do we remove the duplicate green
? As far as which one to remove, we assume that duplicates with uppercase characters are correct.
e.g. keep PHP
remove php
or keep PHP
remove Php
as PHP
has more uppercase characters.
So the result will be
Array ( [0] => Green [1] => blue [2] => yellow )
Notice that the Green with uppercase has been preserved.
Would this work?
$r = array_intersect_key($input, array_unique(array_map('strtolower', $input)));
Doesn't care about the specific case to keep but does the job, you can also try to call asort($input);
before the intersect to keep the capitalized values instead (demo at IDEOne.com).
If you can use PHP 5.3.0, here's a function that does what you're looking for:
<?php
function array_unique_case($array) {
sort($array);
$tmp = array();
$callback = function ($a) use (&$tmp) {
if (in_array(strtolower($a), $tmp))
return false;
$tmp[] = strtolower($a);
return true;
};
return array_filter($array, $callback);
}
$input = array(
'green', 'Green',
'php', 'Php', 'PHP',
'blue', 'yellow', 'blue'
);
print_r(array_unique_case($input));
?>
Output:
Array
(
[0] => Green
[1] => PHP
[3] => blue
[7] => yellow
)
function count_uc($str) {
preg_match_all('/[A-Z]/', $str, $matches);
return count($matches[0]);
}
$input = array(
'green', 'Green', 'yelLOW',
'php', 'Php', 'PHP', 'gREEN',
'blue', 'yellow', 'bLue', 'GREen'
);
$input=array_unique($input);
$keys=array_flip($input);
array_multisort(array_map("strtolower",$input),array_map("count_uc",$input),$keys);
$keys=array_flip(array_change_key_case($keys));
$output=array_intersect_key($input,$keys);
print_r( $output );
will return:
Array
(
[2] => yelLOW
[5] => PHP
[6] => gREEN
[9] => bLue
)
You should first make all values lowercase, then launch array_unique and you are done
Normalize your data first by sending it through strtoupper()
or strtolower()
to make the case consistent. Then use your array_unique().
$normalized = array_map($input, 'strtolower');
$result = array_unique($normalized);
$result = array_map($result, 'ucwords');
print_r($result);
精彩评论