tags:

views:

114

answers:

9

I know there is array_unique function, but I want to remove duplicates. Is there a built-in function or do I have to roll my own.

Example input:

banna, banna, mango, mango, apple

Expected output:

apple
+3  A: 

You can use

$singleOccurences = array_keys(
    array_filter(
        array_count_values(
            array('banana', 'mango', 'banana', 'mango', 'apple' )
        ),
        function($val) {
            return $val === 1;
        }
    )
)

See

Gordon
now that makes sense, still, I like mine more ^^
Hannes
@Hannes I don't -- this is elegant :)
jensgram
A: 

PHP.net http://php.net/manual/en/function.array-unique.php

array array_unique ( array $array [, int $sort_flags = SORT_STRING ] )

Takes an input array and returns a new array without duplicate values.


New solution:


function remove_dupes(array $array){
    $ret_array = array();
    foreach($array as $key => $val){
        if(count(array_keys($val) > 1){
            continue;
        } else { 
            $ret_array[$key] = $val; 
        }
}
The Guy Of Doom
-1 read the example in the question; `array_unique` doesn't work.
meagar
Removes the duplicates, thus making the array contain unique values only. OP, however, want *all* instances of any duplicated value removed, i.e., retain only values which are represented *exactly* once.
jensgram
I dont understand what you mean. it should work. EDIT: oh, like that.
The Guy Of Doom
see new solution
The Guy Of Doom
+1  A: 

If you want to only leave values in the array that are already unique, rather than select one unique instance of each value, you will indeed have to roll your own. Built in functionality is just there to sanitise value sets, rather than filter.

JTrott
+1  A: 

You want to remove any entries that have duplicates, so that you're left with only the entries that were unique in the list? Hmm it does sound like something you'll need to roll your own.

bigp
+1  A: 

There is no existing function; You'll have to do this in two passes, one to count the unique values and one to extract the unique values:

$count = array();
foreach ($values as $value) {
  if (array_key_exists($value, $count))
    ++$count[$value];
  else
    $count[$value] = 1;
}

$unique = array();
foreach ($count as $value => $count) {
  if ($count == 1)
    $unique[] = $value;
}
meagar
+2  A: 

Just write your own simple foreach loop:

$used = array();    
$array = array("banna","banna","mango","mango","apple");

foreach($array as $arrayKey => $arrayValue){
    if(isset($used[$arrayValue])){
        unset($array[$used[$arrayValue]]);
        unset($array[$arrayKey]);
    }
    $used[$arrayValue] = $arrayKey;
}
var_dump($array); // array(1) { [4]=>  string(5) "apple" } 

have fun :)

Hannes
For some reason I didn't think you could change the size of an array that way during a `foreach`, but it seems to work.
meagar
Is there any reason you didn't declare `$used = array()` before the `foreach` loop?
Kendall Hopkins
@Kendall Hopkins it is not necessary, but you are right in the spirit of good coding standards i will add it :)
Hannes
A: 

You can built a function based on array_count_values.

$array = array( "banana","banana","mango","mango","apple" );

$value_count_array = array_count_values( $array );
$value_one_count_array = array_filter( $value_count_array, function ( $value_count ) { return $value_count == 1; } );
$unique_values_only_array = array_keys( $value_one_count_array );

print_r( $unique_values_only_array ); //Array ( [0] => apple )

Also in one line

$unique_values_only_array = array_keys( array_filter( array_count_values( $array ), function ( $value_count ) { return $value_count == 1; } ) );
Kendall Hopkins
+8  A: 

You can use a combination of array_unique, array_diff_assoc and array_diff:

array_diff($arr, array_diff_assoc($arr, array_unique($arr)))
Gumbo
What a bizarrely simple solution.
Kendall Hopkins
Note that although this might be a concise solution, all functions are using Quicksort internally that is in O(n²) in worst case (O(n·log n) in average case). So the total complexity is in O(n²) in worst case too.
Gumbo
A: 

The answer on top looks great, but on a side note: if you ever want to eliminate duplicates but leave the first one, using array_flip twice would be a pretty simple way to do so. array_flip(array_flip(x))

jon_darkstar
you've got `array_unique` for that
The Guy Of Doom