Todd Austin
Todd Austin

Reputation: 53

remove duplicates and move those that had duplicates to beginning of multi-dimensional array php

I'm creating a search function for a csv. With the result of my search I then want to remove duplicates and then move those that had duplicates to the beginning of the array.

  Array
    (
        [0] => Array
        (
            [0] => COD 21
            [1] => 4567
            [2] => Robert Wahl
        )
    [1] => Array
        (
            [0] => RT 5
            [1] => 1234
            [2] => Robert Merrill
        )
    [2] => Array
        (
            [0] => XD 62
            [1] => 1653
            [2] => Robert Hill
        )
    [3] => Array
        (
            [0] => RT 5
            [1] => 1234
            [2] => Robert Merrill
        )
)

I have a function that removes duplicates, but I'm not sure how to get it to move the values that have duplicates to the beginning of the array, and order them according to those with the most duplicates:

function arrayUnique($array) { 
    $aux_ini=array(); 
    $result=array(); 
    for($n=0;$n<count($array);$n++) 
    { 
        $aux_ini[]=serialize($array[$n]); 
    } 
    $mat=array_unique($aux_ini); 
    for($n=0;$n<count($array);$n++) 
    { 
        $result[]=unserialize($mat[$n]); 
    } 
    return $result; 
}

Any and all help is appreciated.

Upvotes: 2

Views: 62

Answers (4)

Steve
Steve

Reputation: 20469

function array_unique_ordered_by_duplicates($array)
{
  //serialize inner arrays
  $serialized = array_map('serialize', $array);
  //create an array indexed by the serialized values, with all keys having a value of 0
  $flipped = array_map(function($el){ 
        return 0; 
      },array_flip($serialized));
  //increment the count each time an element is encountered, thereby gicing duplicates a higher value
  foreach($serialized as $v){
    $flipped[$v]+=1;
  }
  //sort descending on the calculated value, putting the most duplicated items first
  arsort($flipped);
  //return unserialized, deduped, orded array
  return array_map('unserialize',array_keys($flipped));

}

Note that splash58's is a more efficient version of the above, using php's array_count_values, and should be used instead

Upvotes: 2

A Smith
A Smith

Reputation: 631

A little bit funky but I think the code is relatively easy to follow.

$csv = array(array('COD 21','4567','Robert Wahl')
            ,array('RT 5','1234','Robert Merrill')
            ,array('XD 62','1653','Robert Hill')
            ,array('RT 5','1234','Robert Merrill')
            );

echo "Begin...<br>\n";

$serials = array();
$dupeqty = array();
foreach ($csv as $csvkey => $csvdata)
{
  $dupekey = serialize($csvdata);

  if ( !isset($serials[$dupekey]) )
    $serials[$dupekey] = $csvkey;

  if ( !isset($dupeqty[$dupekey]) )
    $dupeqty[$dupekey] = 0;
  $dupeqty[$dupekey]++;
}

arsort($dupeqty);
foreach ($dupeqty as $dupekey => $times)
  echo $dupekey . " occurs $times times<br>\n";

flush();

echo "<br>\n";
echo "Accessing the original array...<br>\n";
foreach ($dupeqty as $dupekey => $times)
{
  $data = $csv[$serials[$dupekey]];
  echo '... data ' . $data[0] . ' ' . $data[1] . ' ' . $data[2] . "<br>\n";
}

Running it generates:

Begin...
a:3:{i:0;s:4:"RT 5";i:1;s:4:"1234";i:2;s:14:"Robert Merrill";} occurs 2 times
a:3:{i:0;s:5:"XD 62";i:1;s:4:"1653";i:2;s:11:"Robert Hill";} occurs 1 times
a:3:{i:0;s:6:"COD 21";i:1;s:4:"4567";i:2;s:11:"Robert Wahl";} occurs 1 times

Accessing the original array...
... data RT 5 1234 Robert Merrill
... data XD 62 1653 Robert Hill
... data COD 21 4567 Robert Wahl

Upvotes: 1

splash58
splash58

Reputation: 26153

function arrayUnique($array) { 
    // count values
    $arr = array_count_values (array_map('serialize',$array)); 
    // sort in desc order
    arsort($arr);
    // take keys and restore array
    return array_map('unserialize',array_keys($arr));
}

Upvotes: 3

user4628565
user4628565

Reputation:

try this,

function array_multidimensional($array)
{
$serialized = array_map('serialize', $array);
$array = array_unique($serialized);
return array_intersect_key($array, $unique);
}

Upvotes: 0

Related Questions