Jump to content

sort and delete duplicates in a multidimensional array?


jjfletch

Recommended Posts

Trying to sort an array by zip, then by distance, and then filter out any duplicates. Right now, my code just yields:

 

Warning: usort() [function.usort]: Invalid comparison function

 

I'm not sure, but I suspect that since this whole thing is in a class, I can't call it the way I'm currently doing?

 

Anyway, I've got an array that looks like this:

Array 
( 
    [0] => Array 
        ( 
            [zip] => '01505' 
            [distance] => '7.8405015332347' 
            [tpid] => 32112                                              
        ) 

    [1] => Array 
        ( 
            [zip] => '01505' 
            [distance] => '6.50172229325415' 
            [tpid] => 32112                                              
        ) 

    [2] => Array 
        ( 
            [zip] => '01505' 
            [distance] => '4.50967688350022' 
            [tpid] => 43444                                              
        ) 

    [3] => Array 
        ( 
            [zip] => '01564' 
            [distance] => '6.91151548994925' 
            [tpid] => 32112                                              
        ) 

    [4] => Array 
        ( 
            [zip] => '02021' 
            [distance] => '6.52192787895371' 
            [tpid] => 43444                                              
        ) 

    [5] => Array 
        ( 
            [zip] => '02021' 
            [distance] => '6.91070971397532' 
            [tpid] => 32112                                              
        ) 
) 

 

First, I'm trying to sort them by zip and second, I'm trying to delete the array element if it's a duplicate and whose distance value is higher than the other one.

 

So, based on the example above, I'm trying to create:

 

Array 
( 
    [0] => Array 
        ( 
            [zip] => '01505' 
            [distance] => '4.50967688350022' 
            [tpid] => 43444                                              
        ) 

    [1] => Array 
        ( 
            [zip] => '01564' 
            [distance] => '6.91151548994925' 
            [tpid] => 32112                                              
        ) 

    [2] => Array 
        ( 
            [zip] => '02021' 
            [distance] => '6.52192787895371' 
            [tpid] => 43444                                              
        ) 
) 

 

This is all within a class. So, I have this:

function cmp($a, $b) { 

                if ($a['zip'] == $b['zip']) { 
                        if ($a['distance'] == $b['distance']) { 
                                return 0; 
                        } 
                        return ($a['distance'] < $b['distance']) ? -1 : 1; 
                } 
                return ($a['zip'] < $b['zip']) ? -1 : 1; 
        } 

function processRes($post) { 
                 $r2=0; 
                 for($i=0; $i < count($post); $i++) { 
                       $fetch = $this->zipProx($post[$i]['zipcode'], $post[$i]['radius']); 
                        for($f = 0; $f < count($fetch); $f++) { 
                                $zips[$r2]['zip'] = "'".$fetch[$f]['zip']."'"; 
                $zips[$r2]['distance'] = "'".$fetch[$f]['distance']."'"; 
                                $zips[$r2]['tpid'] = $post[$i]['tpid']; 
                                $r2++; 
                        } 
                 } 

                 usort($zips, 'cmp'); 
                        for ($z=1, $j=0, $n=count($zips); $z<$n; ++$z) { 
                            if ($zips[$z]['zip'] == $zips[$j]['zip']) { 
                               unset($zips[$z]); 
                            } else { 
                              $j = $z; 
                            } 
                        } 
} 

Well, use an array_multisort for the first 2:

http://www.php.net/manual/en/function.array-multisort.php

 

You see the problem is the way the array is set up doesn't allow for the keys to be searched.  Start with something like this:

 

foreach ($test as $ar){
$zip[]=$ar['zip'];
$distance[]=$ar['distance'];
$tpid[]=$ar['tpid'];
}
array_multisort($zip, $distance, $tpid);

 

 

I think usort() is a much better option here. array_multisort requires you to create separate arrays for each "field" in the multidimensional array. Seems like a lot of overhead to me. The following code works to do as you asked, but I'll leave it to you to make it work inside your class.

 

The following assumes the array is in the variable $locations

function sortLocations($a, $b)
{
    if($a['zip']!=$b['zip'])
    {
        return ($a['zip']>$b['zip']) ? 1 : -1;
    }
    if($a['distance']!=$b['distance'])
    {
        return ($a['distance']>$b['distance']) ? 1 : -1;
    }
    return 0;
}
function dedupeLocations(&$locationAry)
{
    $zipCodes = array();
    foreach($locationAry as $index => $location)
    {
        if(!in_array($location['zip'], $zipCodes))
        {
            $zipCodes[] = $location['zip'];
        }
        else
        {
            unset($locationAry[$index]);
        }
    }
    return;
}

usort($locations, 'sortLocations');
dedupeLocations($locations);

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.