2014-05-16 22 views
3

我正在使用多维数组。每个数组由沿着街道的属性组成,其中一个值是街道地址。按值排序多维数组 - 可能性然后平稳

我想订购这样的数组,使得对于每条街道,奇数地址在偶数地址之前列出。它已经以数字顺序排列(从低到高),所以我唯一想知道的是如何在比赛前排序。

$array = array(
    array('apn' => 345345345, 'sqft' => 1200, 'address' => '323 Pacific Ave.'), 
    array('apn' => 345345342, 'sqft' => 1421, 'address' => '324 Pacific Ave.'), 
    array('apn' => 345345346, 'sqft' => 1012, 'address' => '325 Pacific Ave.'), 
    array('apn' => 345345347, 'sqft' => 1093, 'address' => '328 Pacific Ave.'), 
    array('apn' => 345345353, 'sqft' => 1121, 'address' => '12 Lincoln Ave.'), 
    array('apn' => 345345351, 'sqft' => 1643, 'address' => '13 Lincoln Ave.'), 
    array('apn' => 345345352, 'sqft' => 1222, 'address' => '14 Lincoln Ave.') 
); 

目前,我有以下几点:

usort($array, function($a, $b) 
{ 
    if ($a['address'] % 2 == $b['address'] % 2) { 
     if ($a['address'] == $b['address']) { 
      return 0; 
     } 
     return ($a['address'] < $b['address']) ? -1 : 1; 
    }  
    return ($a['address'] % 2 == 0) ? 1 : -1; 
}); 

的问题是,它会导致所有的找齐之前列出的所有可能性,而不是所有的前夕该街道之前,每个街道的几率如下:

Array 
(
    [0] => Array 
     (
      [apn] => 345345341 
      [sqft] => 1001 
      [address] => 13 Lincoln Ave. 
     ) 
    [1] => Array 
     (
      [apn] => 345345341 
      [sqft] => 1001 
      [address] => 12 Lincoln Ave. 
     ) 

    [2] => Array 
     (
      [apn] => 345345341 
      [sqft] => 1001 
      [address] => 14 Lincoln Ave. 
     ) 

    [3] => Array 
     (
      [apn] => 345345345 
      [sqft] => 1200 
      [address] => 323 Pacific Ave. 
     ) 

    [4] => Array 
     (
      [apn] => 345345341 
      [sqft] => 1001 
      [address] => 325 Pacific Ave. 
     ) 

    [5] => Array 
     (
      [apn] => 345345342 
      [sqft] => 1421 
      [address] => 324 Pacific Ave. 
     ) 

    [6] => Array 
     (
      [apn] => 345345341 
      [sqft] => 1001 
      [address] => 328 Pacific Ave. 
     ) 

) 

回答

1

所以这将是:

usort($array, function($x, $y) 
{ 
    $x = preg_split('/^(\d+)\s+(.*)/', $x['address'], -1 , 3); 
    $y = preg_split('/^(\d+)\s+(.*)/', $y['address'], -1 , 3); 
    $x[2] = $x[0] % 2; 
    $y[2] = $y[0] % 2; 
    if($x[1]==$y[1]) //first level: streets 
    { 
     if($x[2]==$y[2]) //second level: oddity 
     return $x[0]<$y[0]?-1:$x[0]!=$y[0]; //third level: numeric order 
     return $x[2]>$y[2]?-1:1; 
    } 
    return $x[1]<$y[1]?-1:1; 
}); 

注意,你的困难是因为你有,实际上,3级排序:

  • 第一级:街道。你希望街道将在结果数组中排序的顶层
  • 第二层:奇怪。你想奇数数量甚至会
  • 第三级前:自然数值顺序排列 - 同样的古怪里面,你想数将按照自然顺序进行排序

小提琴可用here。此外,preg_split()可能不是分隔号码和街道的最佳解决方案,但我不确定常见情况。对此有一点解释,-1的意思是“对结果中的元素没有限制”,3表示PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY(查看我提供的链接以获取更多详细信息)。