jjfletch Posted April 19, 2010 Share Posted April 19, 2010 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; } } } Quote Link to comment https://forums.phpfreaks.com/topic/198967-sort-and-delete-duplicates-in-a-multidimensional-array/ Share on other sites More sharing options...
andrewgauger Posted April 19, 2010 Share Posted April 19, 2010 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); Quote Link to comment https://forums.phpfreaks.com/topic/198967-sort-and-delete-duplicates-in-a-multidimensional-array/#findComment-1044398 Share on other sites More sharing options...
Psycho Posted April 19, 2010 Share Posted April 19, 2010 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); Quote Link to comment https://forums.phpfreaks.com/topic/198967-sort-and-delete-duplicates-in-a-multidimensional-array/#findComment-1044428 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.