1

So I've been trying to find a solution to remove unique elements from an object array and keep the duplicates but almost all the questions are on how to remove duplicates.

The array looks like this:

[{"No":"123","Product":"Name X","Color":"blue"},
 {"No":"123","Product":"Name X","Color":"green"},
 {"No":"456","Product":"Name X2","Color":"red"},
 {"No":"456","Product":"Name X2","Color":"blue"},
 {"No":"789","Product":"Name X3","Color":"yellow"}]

I need to check No if it's unique and remove it if it is. The array would look like this afterwards:

[{"No":"123","Product":"Name X","Color":"blue"},
 {"No":"123","Product":"Name X","Color":"green"},
 {"No":"456","Product":"Name X2","Color":"red"},
 {"No":"456","Product":"Name X2","Color":"blue"}]

I tried doing get only the duplicates in the first place (MySQL), but all the solutions involved using GROUP BY and HAVING which did return only the duplicate rows but did also combine them.

Leyer1947
  • 13
  • 2
  • But why are you having different colors for the same id? – ka_lin Mar 04 '16 at 17:58
  • Welcome to StackOverflow! You say you've tried some things already - could you post the code you used? – Eoin Mar 04 '16 at 17:59
  • Also you can do this with sql query :-`select No, count(*) as c from group by Product having c >1` . Check reference :- http://stackoverflow.com/questions/1786533/find-rows-that-have-the-same-value-on-a-column-in-mysql
    – Alive to die - Anant Mar 04 '16 at 18:00
  • You could try to remove the duplicates first and then find the value you get and remove it in the original array to get finally the values you want, it's just an idea. – Hail Hydra Mar 04 '16 at 18:01

2 Answers2

1

So you want to remove numbers that only appear once. You can do this in two "passes".

First, build the list of numbers and how often they appear:

$numbers = array_reduce(
    $input,
    function($carry,$value) {
        if( !isset($carry[$value['No']])) $carry[$value['No']] = 0;
        $carry[$value['No']]++;
        return $carry;
    },
    []
);
$uniques = array_filter($numbers,function($n) {return $n == 1;});

Now you have a list of unique numbers. So you can strip out the ones that match those numbers.

$result = array_filter(
    $input,
    function($item) use ($uniques) {
        return !isset($uniques[$item['No']]);
    }
);

Done.

Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
0

I would go for something like this:

$db_result = array(); // Your array with duplicates

$count_occurrences = array();

foreach($db_result as $k=>&$v)
{
    $count_occurrences[$v['No']] = array(
        'key'=>$k,
        'count'=>(isset($count_occurrences[$v['No']]['count']) ? ($count_occurrences[$v['No']]['count'] + 1) : 1)
    );
}
unset($v);

foreach($count_occurrences as &$v)
{
    if($v['count'] === 1)
    {
        unset($db_result[$v['key']]);
    }
}
unset($v);
MonkeyZeus
  • 20,375
  • 4
  • 36
  • 77