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; 
                            } 
                        } 
} 

Link to comment
Share on other sites

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);

 

 

Link to comment
Share on other sites

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);

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • 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.