2010-07-12 49 views
64

Tôi đang cố sắp xếp một mảng đa chiều bằng nhiều khóa và tôi không biết bắt đầu từ đâu. Tôi nhìn vào uasort, nhưng không hoàn toàn chắc chắn làm thế nào để viết một chức năng cho những gì tôi cần.Sắp xếp mảng đa chiều bằng nhiều phím

Tôi cần sắp xếp theo tiểu bang, sau đó là event_type, rồi đến ngày.

mảng của tôi trông như thế này:

Array 
(
    [0] => Array 
     (
      [ID] => 1 
      [title] => Boring Meeting 
      [date_start] => 2010-07-30 
      [time_start] => 06:45:PM 
      [time_end] => 
      [state] => new-york 
      [event_type] => meeting 
     ) 

    [1] => Array 
     (
      [ID] => 2 
      [title] => Find My Stapler 
      [date_start] => 2010-07-22 
      [time_start] => 10:45:AM 
      [time_end] => 
      [state] => new-york 
      [event_type] => meeting 
     ) 

    [2] => Array 
     (
      [ID] => 3 
      [title] => Mario Party 
      [date_start] => 2010-07-22 
      [time_start] => 02:30:PM 
      [time_end] => 07:15:PM 
      [state] => new-york 
      [event_type] => party 
     ) 

    [3] => Array 
     (
      [ID] => 4 
      [title] => Duct Tape Party 
      [date_start] => 2010-07-28 
      [time_start] => 01:00:PM 
      [time_end] => 
      [state] => california 
      [event_type] => party 
     ) 
...... etc 
+1

... và bạn muốn sắp xếp nó như thế nào? – deceze

+0

có thể trùng lặp của [Sắp xếp mảng đa chiều trong PHP] (http://stackoverflow.com/questions/2059255/sorting-multidimensional-array-in-php) – outis

Trả lời

134

Bạn cần array_multisort

$mylist = array(
    array('ID' => 1, 'title' => 'Boring Meeting', 'event_type' => 'meeting'), 
    array('ID' => 2, 'title' => 'Find My Stapler', 'event_type' => 'meeting'), 
    array('ID' => 3, 'title' => 'Mario Party', 'event_type' => 'party'), 
    array('ID' => 4, 'title' => 'Duct Tape Party', 'event_type' => 'party') 
); 

# get a list of sort columns and their data to pass to array_multisort 
$sort = array(); 
foreach($mylist as $k=>$v) { 
    $sort['title'][$k] = $v['title']; 
    $sort['event_type'][$k] = $v['event_type']; 
} 
# sort by event_type desc and then title asc 
array_multisort($sort['event_type'], SORT_DESC, $sort['title'], SORT_ASC,$mylist); 

Tính đến PHP 5.5.0:

array_multisort(array_column($mylist, 'event_type'), SORT_DESC, 
       array_column($mylist, 'title'),  SORT_ASC, 
       $mylist); 

$mylist bây giờ là:

array (
    0 => 
    array (
    'ID' => 4, 
    'title' => 'Duct Tape Party', 
    'event_type' => 'party', 
), 
    1 => 
    array (
    'ID' => 3, 
    'title' => 'Mario Party', 
    'event_type' => 'party', 
), 
    2 => 
    array (
    'ID' => 1, 
    'title' => 'Boring Meeting', 
    'event_type' => 'meeting', 
), 
    3 => 
    array (
    'ID' => 2, 
    'title' => 'Find My Stapler', 
    'event_type' => 'meeting', 
), 
) 
+0

Sử dụng tuyệt vời 'array_multisort()' mà tôi không biết là khả thi. Cảm ơn! – damndaewoo

+0

Anh chàng rực rỡ. –

+0

@Rob Tôi rất tò mò về cách bạn sắp xếp date_start – frazras

3
class Sort { 
    private $actual_order = 'asc'; 
    private $actual_field = null; 

    public function compare_arrays($array1, $array2) { 

     if ($array1[$this->actual_field] == $array2[$this->actual_field]) { 
      return 0; 
     } 
     elseif ($array1[$this->actual_field] > $array2[$this->actual_field]) { 
      return ($this->actual_order == 'asc' ? 1 : -1); 
     } 
     else { 
      return ($this->actual_order == 'asc' ? -1 : 1); 
     } 

    } 


    public function order_array(&$array) { 

     usort($array, array($this, 'compare_arrays')); 

    } 


    public function __construct ($field, $actual_order = 'asc') { 
     $this->actual_field = $field; 
     $this->actual_order = $actual_order; 
    } 

} 

// use 

$sort = new Sort ("state"); 

$sort->order_array($array); 
12

Bạn có thể làm điều đó với usort. Đối số $cmp_function có thể là:

function my_sorter($a, $b) { 
    $c = strcmp($a['state'], $b['state']); 
    if($c != 0) { 
     return $c; 
    } 

    $c = strcmp($a['event_type'], $b['event_type']); 
    if($c != 0) { 
     return $c; 
    } 

    return strcmp($a['date_start'], $b['date_start']); 
} 

Đối với một số tùy ý các lĩnh vực trong PHP 5.3, bạn có thể sử dụng đóng cửa để tạo ra một chức năng so sánh:

function make_cmp($fields, $fieldcmp='strcmp') { 
    return function ($a, $b) use (&$fields) { 
     foreach ($fields as $field) { 
      $diff = $fieldcmp($a[$field], $b[$field]); 
      if($diff != 0) { 
       return $diff; 
      } 
     } 
     return 0; 
    } 
} 

usort($arr, make_cmp(array('state', 'event_type', 'date_start'))) 

Đối với một số tùy ý các lĩnh vực khác nhau trong PHP 5.3:

function make_cmp($fields, $dfltcmp='strcmp') { 
    # assign array in case $fields has no elements 
    $fieldcmps = array(); 
    # assign a comparison function to fields that aren't given one 
    foreach ($fields as $field => $cmp) { 
     if (is_int($field) && ! is_callable($cmp)) { 
      $field = $cmp; 
      $cmp = $dfltcmp; 
     } 
     $fieldcmps[$field] = $cmp; 
    } 
    return function ($a, $b) use (&$fieldcmps) { 
     foreach ($fieldcmps as $field => $cmp) { 
      $diff = call_user_func($cmp, $a[$field], $b[$field]); 
      if($diff != 0) { 
       return $diff; 
      } 
     } 
     return 0; 
    } 
} 

function numcmp($a, $b) { 
    return $a - $b; 
} 
function datecmp($a, $b) { 
    return strtotime($a) - strtotime($b); 
} 
/** 
* Higher priority come first; a priority of 2 comes before 1. 
*/ 
function make_evt_prio_cmp($priorities, $default_priority) { 
    return function($a, $b) use (&$priorities) { 
     if (isset($priorities[$a])) { 
      $prio_a = $priorities[$a]; 
     } else { 
      $prio_a = $default_priority; 
     } 
     if (isset($priorities[$b])) { 
      $prio_b = $priorities[$b]; 
     } else { 
      $prio_b = $default_priority; 
     } 
     return $prio_b - $prio_a; 
    }; 
} 

$event_priority_cmp = make_evt_prio_cmp(
    array('meeting' => 5, 'party' => 10, 'concert' => 7), 
    0); 

usort($arr, make_cmp(array('state', 'event' => $event_priority_cmp, 'date_start' => 'datecmp', 'id' => 'numcmp'))) 
+1

Bạn có thể đơn giản hóa việc làm tổ khá một chút, và tôi nghĩ bạn sẽ cần phải làm một cái gì đó nhiều hơn với ngày, nhưng cách tiếp cận có vẻ tốt nhất cho đến nay. – deceze

+0

Điều tốt đẹp về định dạng '% Y-% m-% d' được sử dụng trong mảng mẫu là so sánh chuỗi hoạt động cho so sánh ngày. – outis

3

tôi đã cố gắng bên dưới mã và tôi thành công

.210

đang mảng

$songs = array(
     '1' => array('artist'=>'Smashing Pumpkins', 'songname'=>'Soma'), 
     '2' => array('artist'=>'The Decemberists', 'songname'=>'The Island'), 
     '3' => array('artist'=>'Fleetwood Mac', 'songname' =>'Second-hand News') 
); 

mảng gọi sắp xếp chức năng

$songs = subval_sort($songs,'artist'); 
print_r($songs); 

mảng sắp xếp funcation

function subval_sort($a,$subkey) { 
    foreach($a as $k=>$v) { 
     $b[$k] = strtolower($v[$subkey]); 
    } 
    asort($b); 
    foreach($b as $key=>$val) { 
     $c[] = $a[$key]; 
    } 
    return $c; 
} 

nếu mảng đảo ngược sắp xếp chức năng

function subval_sort($a,$subkey) { 
     foreach($a as $k=>$v) { 
      $b[$k] = strtolower($v[$subkey]); 
     } 
     arsort($b); 
     foreach($b as $key=>$val) { 
      $c[] = $a[$key]; 
     } 
     return $c; 
    } 
1

Cải thiện trên @Stijn đang thiên tài Leenknegt của, đây là 2 phần trăm chức năng thực dụng của tôi:

$data[] = array('volume' => 67, 'edition' => 2); 
$data[] = array('volume' => 86, 'edition' => 1); 
$data[] = array('volume' => 85, 'edition' => 6); 
$data[] = array('volume' => 98, 'edition' => 2); 
$data[] = array('volume' => 86, 'edition' => 6); 
$data[] = array('volume' => 67, 'edition' => 7); 

function make_cmp(array $sortValues) 
{ 
    return function ($a, $b) use (&$sortValues) { 
     foreach ($sortValues as $column => $sortDir) { 
      $diff = strcmp($a[$column], $b[$column]); 
      if ($diff !== 0) { 
       if ('asc' === $sortDir) { 
        return $diff; 
       } 
       return $diff * -1; 
      } 
     } 
     return 0; 
    }; 
} 

usort($data, make_cmp(['volume' => "desc", 'edition' => "asc"])); 
0

nếu bạn muốn sắp xếp mảng đa dimentional

mảng đầu tiên là:

$results['total_quote_sales_person_wise']['quote_po']; 

thứ hai là:

$results['total_quote_sales_person_wise']['quote_count']; 

cả hai mảng đa chiều này bạn muốn sắp xếp thứ tự giảm dần cùng một lúc, sau đó sử dụng mã này:

array_multisort($results['total_quote_sales_person_wise']['quote_po'],SORT_DESC, $results['total_quote_sales_person_wise']['quote_count'],SORT_DESC); 
Các vấn đề liên quan