2010-03-11 100 views
12

假设我有一个模仿数据库表的数组。每个数组元素表示一个行,并且每行中的另一个数组包含字段名称和值。如何通过PHP中的内部数组的一个字段对多维数组进行排序?

Array 
(
    [0] => Array 
     (
      [name] => 'Sony TV' 
      [price] => 600.00 
     ) 

    [1] => Array 
     (
      [name] => 'LG TV' 
      [price] => 350.00 
     ) 

    [2] => Array 
     (
      [name] => 'Samsung TV' 
      [price] => 425.00 
     ) 
} 

我想要做的是按价格对行(外部数组元素)进行排序。以下是我想实现的一个示例:

Array 
(
    [0] => Array 
     (
      [name] => 'LG TV' 
      [price] => 350.00 
     ) 

    [1] => Array 
     (
      [name] => 'Samsung TV' 
      [price] => 425.00 
     ) 

    [2] => Array 
     (
      [name] => 'Sony TV' 
      [price] => 600.00 
     )   
} 

正如您所看到的,我不需要保留外部数组的键。

+0

注意:如果您的数据来自数据库,请在选择时使用数据库的排序方法。 – DisgruntledGoat 2010-03-11 17:18:25

+0

Duplicate:http://stackoverflow.com/questions/2122062/sort-multidimensional-array-of-objects – 2010-03-11 17:18:42

+0

@DisgruntledGoat它不是来自数据库。我只是以此为例。它实际上来自第三方XML。 – Camsoft 2010-03-11 17:25:50

回答

23

您需要使用usort,这是一个通过用户定义的函数对数组进行排序的函数。像这样的:

function cmp($a, $b) 
{ 
    if ($a["price"] == $b["price"]) { 
     return 0; 
    } 
    return ($a["price"] < $b["price"]) ? -1 : 1; 
} 

usort($yourArray,"cmp") 
10

您可以使用usort()

function sort($a, $b) { 
    if ($a['price'] == $b['price']) return 0; 
    return ($a['price'] > $b['price']) ? 1 : -1; 
} 

usort($array, 'sort'); 
如果你创建一个这样的类重用代码

更妙的是:

class FieldSorter { 
    public $field; 

    function __construct($field) { 
     $this->field = $field; 
    } 

    function cmp($a, $b) { 
     if ($a[$this->field] == $b[$this->field]) return 0; 
     return ($a[$this->field] > $b[$this->field]) ? 1 : -1; 
    } 
} 

$sorter = new FieldSorter('price');  
usort($array, array($sorter, "cmp")); 

这样,你可以很容易地按其他字段排序。

虽然您说外部阵列的密钥不必保留,但您可以使用uasort()而不是usort轻松实现此目的。

+1

班级建议非常棒! – MastaBaba 2014-08-20 17:14:21

1

这个问题有点旧,但会留下答案在这里为将来。

php.net-Multisort 函数我们可以使用下面的代码;

$data= [['volume' => 67, 'edition' => 2],['volume' => 85, 'edition' => 6],...]; 
foreach ($data as $key => $row) { 
    $volume[$key] = $row['volume']; 
    $edition[$key] = $row['edition']; 
} 
array_multisort($volume, SORT_DESC, $edition, SORT_ASC, $data); 

以上是对手动更改排序列的数据进行静态排序。

对于更具动态性和鲁棒性的示例,请在下面考虑;

假设我有以下数据;

$data = [[1, 'Amanda', 'Wright', '[email protected]', 'Female', '135.114.57.89', 31237], 
      [2, 'Theresa', 'Larson', '[email protected]', 'Female', '207.108.96.210', 91011], 
      [3, 'Walter', 'Kennedy', '[email protected]', 'Male', '199.147.223.56', 50114], 
      [4, 'Andrea', 'Richards', '[email protected]', 'Female', '230.195.124.95', 76489], 
      [5, 'Carol', 'Jones', '[email protected]', 'Female', '250.197.111.90', 56501], 
      [6, 'Alice', 'Freeman', '[email protected]', 'Female', '52.195.252.131', 77170], 
      [7, 'Gerald', 'Fisher', '[email protected]', 'Male', '81.2.22.62', 75625],....] 

如果我们需要在上述阵列数据开箱排序,那么我们就可以在阵列中使用的语法设置排序订单;

$qTable[$index]=$sort_order; 
E.g. $qTable=[1=>'asc',4=>'desc',3=>'asc']; 

这意味着对第1列ASC,第4列DESC和第3列ASC进行排序。 然后我们可以使用下面的函数对我们的多维数据库数据进行排序;

function sortMulti($data, $orders) 
    { 
     $args = []; 
     foreach ($data as $key => $row) { 
      foreach ($orders as $index => $order) { 
       if (!isset($row[$index])) continue; //Ignore if column does'nt exist 
       $args[$index]['d'][$key] = $row[$index]; //Get all values within the column 
       $args[$index]['o']  = 'desc' == strtolower($order) ? SORT_DESC : SORT_ASC; //Get the Sort order 'ASC' is the default 
      } 
     } 
     $p = []; 
//Below we need to organize our entries as arguments for array_multisort 
     foreach ($args as $arg) { 
      $p[] = $arg['d']; 
      $p[] = $arg['o']; 
//Below we need to check if column contains only numeric or not. 
//If all values are numeric, then we use numeric sort flag, otherwise NATURAL 
//Manipulate for more conditions supported 
      $p[] = count($arg['d']) == count(array_filter($arg['d'], 'is_numeric')) ? SORT_NUMERIC : SORT_NATURAL; 
     } 
     $p[] = &$data; //Pass by reference 
     call_user_func_array('array_multisort', $p); //Call Php's own multisort with parameters in required order. 
     return $data; //Our final array sorted. 
    } 

然后我们可以如下使用它;

$data=[[...],[...],...]; 
$order=[1=>'asc',4=>'desc',3=>'asc']; 

$sorted=sortMulti($data,$order); 

对于关键值阵列数据E.g. $data=[['c1'=>1212,'c2'=>'mynames'],...]; 用作$order=['c1'=>'desc','c10'=>'asc'];

我测试了以上的1000个记录的阵列的顺序。 希望它可以帮助别人。

+0

不错,这也适用于非数字键 – 2017-10-26 18:32:35

0

usort的替代方法是创建一个数组,用于索引要排序的数组,并按您希望排序的数据进行索引。

在下面的代码片段,$ customAttributes是,我想通过排序对象的数组。第一个$排序已创建,索引名称并包含相应的数组索引$ customAttributes元素。然后

$sort = []; 
foreach($customAttributes as $c => $ca) 
{ 
    $sort[$ca->name] = $c; 
} 

ksort用于由密钥对数组进行排序。

ksort($sort); 

一旦$排序阵列已经被排序,遍历并创建$有序阵列。

$ordered = []; 
foreach($sort as $s) 
{ 
    $ordered[] = $customAttributes[$s]; 
} 

我喜欢这个解决方案,因为比使用回调函数调用更少。

0

您可以创建一个函数自己像下面

私有函数orderArrayBycolumn($数组$列){

$newArray = []; 
    foreach ($array as $key => $value) { 
     $newArray[$value[$column]] = $value; 
    } 

    $array = []; 

    ksort($newArray); 

    foreach ($newArray as $key => $value) { 
     $array[] = $value; 
    }  

    return $array; 
} 
相关问题