2

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.

4 Answers4

3
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));
}
splash58
  • 26,043
  • 3
  • 22
  • 34
2
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

Steve
  • 20,703
  • 5
  • 41
  • 67
1

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
A Smith
  • 621
  • 1
  • 4
  • 10
  • this looks a lot like what I started out coding, but for some reason I ran into issues if there were more than 2 matching entries. – Todd Austin Jul 09 '15 at 16:41
  • To be sure I have tested it and it does work with more than two matching entries. The concise answer is obviously the best but perhaps some will find this one illustrative. – A Smith Jul 09 '15 at 17:06
0

try this,

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