2011-12-21 121 views
1

成品数组排序数组将是这个样子:PHP,通过密钥长度和值

array(

'foo bar bar foo' => 10, 
'foo' => 10, 
'foo bar bar bar foo' => 6, 
'foo bar' => 6, 
'bar' => 6, 
'b' => 5 

) 

所以值由值第一排序,然后由密钥的长度。

在MySQL我应该这样做:

SELECT product, qty FROM stock ORDER BY qty DESC, LENGTH(product) DESC 

但我想做到这一点在PHP。

+0

也,是否有一个特别的原因,你想在PHP中做到这一点? – Ascherer 2011-12-21 21:09:12

+0

@Ascherer:数据不在MySQL中,我想避免将所有数据都放在那里的传输时间。我的SELECT语句只是一个例子。 – Drahcir 2011-12-21 21:12:05

+0

ahh,k。这很有道理 – Ascherer 2011-12-21 21:23:40

回答

3

看看这个问题的答案:PHP array multiple sort - by value then by key?,似乎array_multisort是要走的路。 (我不太确定array_multisort是如何工作的,我只是有点黑了,它似乎工作)。

试试这个:

$arr = array(
    'foo bar' => 6, 
    'foo' => 10, 
    'bar' => 6, 
    'b' => 5, 
    'foo bar bar bar foo' => 6, 
    'foo bar bar foo' => 10 
); 

array_multisort(array_values($arr), SORT_DESC, 
    array_map(create_function('$v', 'return strlen($v);'), array_keys($arr)), 
    SORT_DESC, $arr); 

演示:http://codepad.org/mAttNIV7

更新:新增array_map排序依据的字符串的长度使得它,它只是在做之前:

$str1 > $str2,而不是strlen($str1) > strlen($str2)

更新2:在PHP> = 5.3中,您可以用真正的匿名函数替换create_function

array_map(function($v){return strlen($v);}, array_keys($arr)) 

演示2:http://codepad.viper-7.com/6qrFwj

+0

嗯,是的,这种方式比我原来的阵列效果更好,我原本避免了这个原因,我没有认为它会按字符串排序的长度,但它看起来像是lol – Ascherer 2011-12-21 21:24:58

+0

@Ascherer:它最初是通过做'$ a> $ b',它不是按长度排序的,它恰好是按照这个顺序排列的。我添加了一个'array_map'来使它排序。 – 2011-12-21 21:31:56

+0

@火箭:感谢您花时间解决这个问题,您已经完美地解决了我的问题。 – Drahcir 2011-12-21 21:35:18

3

看看php的usortuasort

你应该能够定义一个能像

不知道对其进行排序的功能是否会与当前的阵列很容易的工作,但这个会

$array = array(
array('name' => 'foo bar bar foo', 'qty' => 10), 
array('name' => 'foo', 'qty' => 6), 
array('name' => 'foo bar bar foo', 'qty' => 6), 
array('name' => 'foo bar', 'qty' => 6) 
); 

uasort($array, 'arraySort'); 

function arraySort($a, $b) 
{ 
    if($a['qty'] > $b['qty']) 
     return 1; 
    elseif($a['qty'] < $b['qty']) 
     return -1; 
    else 
     if(strlen($a['name']) >= strlen($b['name'])) 
      return 1; 
     else 
      return -1; 
} 
-2

使用排序功能PHP。确保你使用TRUE作为第二个参数来保存密钥。

+0

['sort'](http://php.net/sort)没有“保留键”参数。如果你想这样做,你可以使用['asort'](http://php.net/asort)。 – 2011-12-21 21:03:21

0

一个限制而排序长度的基础上的键为:长度相等键不重新排序。假设我们需要按照订单号descending的顺序排序。

$arr = array(
    "foo 0" => "apple", 
    "foo 1" => "ball", 
    "foo 2 foo 0 foo 0" => "cat", 
    "foo 2 foo 0 foo 1 foo 0" => "dog", 
    "foo 2 foo 0 foo 1 foo 1" => "elephant", 
    "foo 2 foo 1 foo 0" => "fish", 
    "foo 2 foo 1 foo 1" => "giraffe" 
); 

debug($arr, "before sort"); 
$arrBad = $arr; 
sortKeysDescBAD($arrBad); 
debug($arrBad, "after BAD sort"); 
sortKeysDescGOOD($arr); 
debug($arr, "after GOOD sort 2"); 

function sortKeysDescBAD(&$arrNew) { 
    $arrKeysLength = array_map('strlen', array_keys($arrNew)); 
    array_multisort($arrKeysLength, SORT_DESC, $arrNew); 
    //return max($arrKeysLength); 
} 

function sortKeysDescGOOD(&$arrNew) { 
    uksort($arrNew, function($a, $b) { 
     $lenA = strlen($a); $lenB = strlen($b); 
     if($lenA == $lenB) { 
      // If equal length, sort again by descending 
      $arrOrig = array($a, $b); 
      $arrSort = $arrOrig; 
      rsort($arrSort); 
      if($arrOrig[0] !== $arrSort[0]) return 1; 
     } else { 
      // If not equal length, simple 
      return $lenB - $lenA; 
     } 
    }); 
} 

function debug($arr, $title = "") { 
    if($title !== "") echo "<br/><strong>{$title}</strong><br/>"; 
    echo "<pre>"; print_r($arr); echo "</pre><hr/>"; 
} 

输出将是:

before sort 
Array 
(
    [foo 0] => apple 
    [foo 1] => ball 
    [foo 2 foo 0 foo 0] => cat 
    [foo 2 foo 0 foo 1 foo 0] => dog 
    [foo 2 foo 0 foo 1 foo 1] => elephant 
    [foo 2 foo 1 foo 0] => fish 
    [foo 2 foo 1 foo 1] => giraffe 
) 

after BAD sort 
Array 
(
    [foo 2 foo 0 foo 1 foo 0] => dog 
    [foo 2 foo 0 foo 1 foo 1] => elephant 
    [foo 2 foo 0 foo 0] => cat 
    [foo 2 foo 1 foo 0] => fish 
    [foo 2 foo 1 foo 1] => giraffe 
    [foo 0] => apple 
    [foo 1] => ball 
) 

after GOOD sort 
Array 
(
    [foo 2 foo 0 foo 1 foo 1] => elephant 
    [foo 2 foo 0 foo 1 foo 0] => dog 
    [foo 2 foo 1 foo 1] => giraffe 
    [foo 2 foo 1 foo 0] => fish 
    [foo 2 foo 0 foo 0] => cat 
    [foo 1] => ball 
    [foo 0] => apple 
) 

通知elephantdog例如(或其他人)在两个分拣方法的顺序。第二种方法看起来更好。有可能是更简单的方法来解决这个问题,但希望这可以帮助别人......