0

When I print $online_performers variable I want to get a unique value for id 2. Do I need to convert them in standard array first or is that possible without it? (remove all duplicates).Please check my new code for this.

 Array
        (
            [0] => stdClass Object
            (
                [id] => 1
                [username] => Sample1
            )
            [1] => stdClass Object
            (
                [id] => 2
                [username] => Sample1
            )
           [2] => stdClass Object
            (
                [id] => 2
                [username] => Sample1
            )
           [3] => stdClass Object
            (
                [id] => 4
                [username] => Sample4
            )
        )



to
    Array
        (
            [0] => stdClass Object
            (
                [id] => 1
                [username] => Sample1
            )
            [1] => stdClass Object
            (
                [id] => 4
                [username] => Sample4
            )
        )
8
  • Are you sure you want to loose BOTH classes that contain the property [id] = 2??? Commented Aug 5, 2014 at 11:51
  • yes,they are duplicates Commented Aug 5, 2014 at 11:52
  • Yes but that usually means you keep one of them and delete one of them? Commented Aug 5, 2014 at 11:52
  • sorry my mistake i updated my code.i want to eliminate duplicate Commented Aug 5, 2014 at 11:54
  • Will duplicates always be together or do you want to check the whole array for possible duplicates. Commented Aug 5, 2014 at 11:56

3 Answers 3

2

PHP has a function called array_filter() for that purpose:

$filtered = array_filter($array, function($item) {
    static $counts = array();
    if(isset($counts[$item->id])) {
        return false;
    }

    $counts[$item->id] = true;
    return true;
});

Note the usage of the static keyword. If used inside a function, it means that a variable will get initialized just once when the function is called for the first time. This gives the possibility to preserve the lookup table $counts across multiple function calls.


In comments you told, that you also search for a way to remove all items with id X if X appears more than once. You could use the following algorithm, which is using a lookup table $ids to detect elements which's id occur more than ones and removes them (all):

$array = array("put your stdClass objects here");

$ids = array();
$result = array();

foreach($array as $item) {
    if(!isset($ids[$item->id])) {
        $result[$item->id]= $item;
        $ids[$item->id] = true;
    } else {
        if(isset($result[$item->id])) {
            unset($result[$item->id]);
        }
    }
}

$result = array_values($result);
var_dump($result);
Sign up to request clarification or add additional context in comments.

11 Comments

hi is this possible to remove duplicates totally?
You mean removing every item that occurs multiple times?
@vishal I don't a fancy way. You would need to iterate over the array, count occurrences and remove those which are duplicates in a second loop afterwards.
HI your first algorithm was working fine second one not working properly i placed my array as $array = array($online_performers); but its not working fine.In your fist algorithm it removes duplicate but it keeps 1 for eg if id=2 comes 3 times in array than it will replace two and keep 1 instead of that i want to delete all those item which are duplicate.Thanks.
@vishal Oh, did I missed something? ... Let me check this ..
|
1

If you don't care about changing your keys you could do this with a simple loop:

$aUniq = array ();
foreach($array as $obj) {
    $aUniq[$obj->id] = $obj;
}

print_r($aUniq);

Comments

1

Let's say we have:

$array = [
   //items 1,2,3 are same
   (object)['id'=>1, 'username'=>'foo'],
   (object)['id'=>2, 'username'=>'bar'],
   (object)['id'=>2, 'username'=>'baz'],
   (object)['id'=>2, 'username'=>'bar']
];

Then duplication depends of what do you mean. For instance, if that's about: two items with same id are treated as duplicates, then:

$field = 'id';

$result = array_values(
   array_reduce($array, function($c, $x) use ($field)
   {
      $c[$x->$field] = $x;
      return $c;
   }, [])
);

However, if that's about all fields, which should match, then it's a different thing:

$array = [
   //1 and 3 are same, 2 and 3 are not:
   (object)['id'=>1, 'username'=>'foo'],
   (object)['id'=>2, 'username'=>'bar'],
   (object)['id'=>2, 'username'=>'baz'],
   (object)['id'=>2, 'username'=>'bar']
];

You'll need to identify somehow your value row. Easiest way is to do serialize()

$result = array_values(
   array_reduce($array, function($c, $x)
   {
      $c[serialize($x)] = $x;
      return $c;
   }, [])
);

But that may be slow since you'll serialize entire object structure (so you'll not see performance impact on small objects, but for complex structures and large amount of them it's sounds badly)

Also, if you don't care about keys in resulting array, you may omit array_values() call, since it serves only purpose of making keys numeric consecutive.

19 Comments

Thats deliciously elegant, but its checking username and he wants to check the [id] field.
@RiggsFolly I've made an option for that too (see first explanation)
Ah thanks missed that, now I just have to work out what it all means.
Hi alma thanks,in my case i have merged two arrays so i dont want to keep any other entery with same id for eg keep 1 and 2 only and remove other with id2 from the array you made (object)['id'=>1, 'username'=>'foo'], (object)['id'=>2, 'username'=>'bar']
And.. What? If they are duplicates, then by definition it doesn't matter which of them to keep
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.