2013-01-25 98 views
0

我想按以下顺序按多个键对以下数组排序:首先按“type”,然后“product”,最后按“name”。这很容易用usort完成,尽管我的客户希望“产品”按特定顺序排序:订书机,活页夹,书本。按一定顺序按多个键对数组排序

$arr = array(
    array(
     'type' => 'School', 
     'product' => 'Book', 
     'name' => 'My book', 
     'data' => '...' 
    ), 
    array(
     'type' => 'Job', 
     'product' => 'Stapler', 
     'name' => 'My stapler', 
     'data' => '...' 
    ), 
    array(
     'type' => 'Personal', 
     'product' => 'Binder', 
     'name' => 'My binder', 
     'data' => '...' 
    ), 
    array(
     'type' => 'School', 
     'product' => 'Book', 
     'name' => 'My book', 
     'data' => '...' 
    ) 
); 

有谁知道一个聪明的方式来做到这一点?

+0

你想是这样的array( 'type' => 'School', 'type' => 'Job', 'type' => 'Personal' )

回答

1
usort($arr, function ($a, $b) { 
    // by type 
    $r = strcmp($a['type'], $b['type']); 
    if ($r !== 0) { 
    return $r; 
    } 

    // by product 
    // note: one might want to check if `$a/$b['product']` really is in `$order` 
    $order = array('Stapler', 'Binder', 'Book'); 
    $r = array_search($a['product'], $order) - array_search($b['product'], $order); 
    if ($r !== 0) { 
    return $r; 
    } 

    // or similar, with a little help by @fab ;) 
    /* 
    $order = array('Stapler' => 0, 'Binder' => 1, 'Book' => 2); 
    $r = $order[$a['product']] - $order[$b['product']]; 
    if ($r !== 0) { 
    return $r; 
    } 
    */ 

    // name 
    return strcmp($a['name'], $b['name']); 
}); 
+0

好极了!谢谢。 – frigg

1

usort不会限制你这样做。我假设你的问题是如何比较排序回调函数中的product值。这可以用地图来完成,如:

$mapProductOrder = array_flip(array('Stapler', 'Binder', 'Book')); 
// same as: array('Stapler' => 0, 'Binder' => 1, 'Book' => 2) 

比较$item1$item2使用:

$mapProductOrder[$item1['product']] < $mapProductOrder[$item2['product']]