Bu soru burada zaten bir cevabı var:
Sen kullanabilirsiniz array_multisort()
Böyle bir şey deneyin:
foreach ($mdarray as $key => $row) {
$dates[$key] = $row[0];
// of course, replace 0 with whatever is the date field's index
}
array_multisort($dates, SORT_DESC, $mdarray);
Ben başka bir cevap olmadığını özellikler sunuyor beri, burada kendi çözüm eklemek istiyorum '.
Özel olarak, bu çözeltinin avantajları şunlardır:
DateTime
örneği).usort
veya uasort
) seçeneğini seçin: Bu associative if you want bulunuyor.array_multisort
: array_multisort
uygun ise, bu sıralamadan önce tüm veri girişi bir projeksiyon oluşturma bağlıdır. Bu zaman ve bellek tüketir ve veri kümesi büyükse sadece engelleyici olabilir.function make_comparer() {
// Normalize criteria up front so that the comparer finds everything tidy
$criteria = func_get_args();
foreach ($criteria as $index => $criterion) {
$criteria[$index] = is_array($criterion)
? array_pad($criterion, 3, null)
: array($criterion, SORT_ASC, null);
}
return function($first, $second) use (&$criteria) {
foreach ($criteria as $criterion) {
// How will we compare this round?
list($column, $sortOrder, $projection) = $criterion;
$sortOrder = $sortOrder === SORT_DESC ? -1 : 1;
// If a projection was defined project the values now
if ($projection) {
$lhs = call_user_func($projection, $first[$column]);
$rhs = call_user_func($projection, $second[$column]);
}
else {
$lhs = $first[$column];
$rhs = $second[$column];
}
// Do the actual comparison; do not return if equal
if ($lhs < $rhs) {
return -1 * $sortOrder;
}
else if ($lhs > $rhs) {
return 1 * $sortOrder;
}
}
return 0; // tiebreakers exhausted, so $first == $second
};
}
Bu bölüm boyunca ben bu örnek veri seti sıralamak bağlantıları sağlayacak:
$data = array(
array('zz', 'name' => 'Jack', 'number' => 22, 'birthday' => '12/03/1980'),
array('xx', 'name' => 'Adam', 'number' => 16, 'birthday' => '01/12/1979'),
array('aa', 'name' => 'Paul', 'number' => 16, 'birthday' => '03/11/1987'),
array('cc', 'name' => 'Helen', 'number' => 44, 'birthday' => '24/06/1967'),
);
Fonksiyonu make_comparer
istenen sıralama tanımlamak bağımsız değişken bir dizi kabul eder ve usort
veya uasort
için argüman olarak kullanmak gerekiyor bir işlevi döndürür.
Basit kullanımı durumda size 'veri öğeleri karşılaştırmak için kullanmak istiyorum anahtarında geçmektir. Örneğin, sen yapardın name
öğesi tarafından $data
sıralamak için
usort($data, make_comparer('name'));
See it in action strong>.
Öğeleri sayısal indisli diziler ise anahtar da bir sayı olabilir. Söz konusu örnekte, bu olur
usort($data, make_comparer(0)); // 0 = first numerically indexed column
See it in action strong>.
Sen make_comparer
ek parametreler ileterek birden fazla sıralama sütun belirtebilirsiniz. Örneğin, "sayı" göre sıralamak ve daha sonra sıfır endeksli sütuna tarafından:
usort($data, make_comparer('number', 0));
See it in action strong>.
Eğer bir dizinin yerine basit bir dizge olarak bir sıralama sütunu belirtmek eğer daha gelişmiş özellikler bulunmaktadır. Bu dizi sayısal endeksli olmalıdır ve bu öğeleri içermelidir:
0 => the column name to sort on (mandatory)
1 => either SORT_ASC or SORT_DESC (optional)
2 => a projection function (optional)
Kullanıcının bu özelliklerini nasıl kullanılacağını görelim.
Adı azalan göre sıralamak için:
usort($data, make_comparer(['name', SORT_DESC]));
See it in action strong>.
Numarası azalan tarafından ve daha sonra isim azalan göre sıralamak için:
usort($data, make_comparer(['number', SORT_DESC], ['name', SORT_DESC]));
See it in action strong>.
Bazı senaryolarda, değerleri sıralama iyi borç yoktur bir sütuna göre sıralamak gerekebilir. Örnek veri seti "doğum günü" sütunu bu tanıma uyan: (örneğin "01/01/1980", "1970/10/10" önce gelir çünkü) dizeleri gibi doğum günlerini karşılaştırmak mantıklı değil. Bu durumda biz belirtmek istiyorum nasıl can istenen semantik ile doğrudan karşılaştırıldığında bir form project gerçek veri için.
Projeksiyonlar callable herhangi bir türü olarak belirtilebilir: dizeleri, diziler veya anonim fonksiyonlar gibi. Bir projeksiyon bir argüman kabul ve öngörülen formu varsayılır.
Bu projeksiyonlar usort
ve ailesi ile kullanılan özel karşılaştırma işlevlerine benzer iken, bunlar basit vardır (sadece başka bir değere dönüştürmek gerekir) ve zaten içine pişmiş tüm işlevsellikten yararlanmak unutulmamalıdır make_comparer
.
Adlı bir projeksiyon olmadan seti örnek verileri sıralamak ve ne görelim:
usort($data, make_comparer('birthday'));
See it in action strong>.
Yani istenen sonuç değildi. Ama biz bir projeksiyon olarak date_create
a> kullanabilirsiniz:
usort($data, make_comparer(['birthday', SORT_ASC, 'date_create']));
See it in action strong>.
Bu, bu istedik doğru emirdir.
Projeksiyonları elde edebilirsiniz ki daha çok şey vardır. Örneğin, bir harf duyarsız bir tür almak için hızlı bir şekilde bir projeksiyon olarak strtolower
kullanmaktır.
O dedi, ben de senin veri seti büyük ise o projeksiyonlar kullanmak daha iyi olduğunu belirtmek gerekir: bu durumda, bunu yaparken de, bir projeksiyon kullanmadan elle ön ve ardından sıralama tüm verilerinizi proje için çok daha hızlı olurdu ticaret yapacak Daha hızlı sıralama hızı artan bellek kullanımı.
Son olarak, burada tüm özelliklerini kullanan bir örnek: O sayı Azalan ilk sıralar, doğum günü Artan:
usort($data, make_comparer(
['number', SORT_DESC],
['birthday', SORT_ASC, 'date_create']
));
See it in action strong>.
Ile usort. Burada genel bir çözüm, farklı sütunlar için kullanabileceğiniz, var:
class TableSorter {
protected $column;
function __construct($column) {
$this->column = $column;
}
function sort($table) {
usort($table, array($this, 'compare'));
return $table;
}
function compare($a, $b) {
if ($a[$this->column] == $b[$this->column]) {
return 0;
}
return ($a[$this->column] < $b[$this->column]) ? -1 : 1;
}
}
İlk sütuna göre sıralamak için:
$sorter = new TableSorter(0); // sort by first column
$mdarray = $sorter->sort($mdarray);
Ben bu soruyu sordu ve cevap oldu bu yana 2 yıl var biliyorum, ama burada iki boyutlu bir diziyi sıralar başka bir fonksiyon. Bu göre sıralamak için birden fazla anahtar (yani sütun adı) geçmesine izin, bağımsız değişken bir dizi kabul eder. PHP 5.3 gereklidir.
function sort_multi_array ($array, $key)
{
$keys = array();
for ($i=1;$i<func_num_args();$i++) {
$keys[$i-1] = func_get_arg($i);
}
// create a custom search function to pass to usort
$func = function ($a, $b) use ($keys) {
for ($i=0;$i<count($keys);$i++) {
if ($a[$keys[$i]] != $b[$keys[$i]]) {
return ($a[$keys[$i]] < $b[$keys[$i]]) ? -1 : 1;
}
}
return 0;
};
usort($array, $func);
return $array;
}
Burada deneyin: http://www.exorithm.com/algorithm/view/sort_multi_array
Burada bir veya daha fazla alan sıralamak bir PHP4/PHP5 sınıftır:
// a sorter class
// php4 and php5 compatible
class Sorter {
var $sort_fields;
var $backwards = false;
var $numeric = false;
function sort() {
$args = func_get_args();
$array = $args[0];
if (!$array) return array();
$this->sort_fields = array_slice($args, 1);
if (!$this->sort_fields) return $array();
if ($this->numeric) {
usort($array, array($this, 'numericCompare'));
} else {
usort($array, array($this, 'stringCompare'));
}
return $array;
}
function numericCompare($a, $b) {
foreach($this->sort_fields as $sort_field) {
if ($a[$sort_field] == $b[$sort_field]) {
continue;
}
return ($a[$sort_field] < $b[$sort_field]) ? ($this->backwards ? 1 : -1) : ($this->backwards ? -1 : 1);
}
return 0;
}
function stringCompare($a, $b) {
foreach($this->sort_fields as $sort_field) {
$cmp_result = strcasecmp($a[$sort_field], $b[$sort_field]);
if ($cmp_result == 0) continue;
return ($this->backwards ? -$cmp_result : $cmp_result);
}
return 0;
}
}
/////////////////////
// usage examples
// some starting data
$start_data = array(
array('first_name' => 'John', 'last_name' => 'Smith', 'age' => 10),
array('first_name' => 'Joe', 'last_name' => 'Smith', 'age' => 11),
array('first_name' => 'Jake', 'last_name' => 'Xample', 'age' => 9),
);
// sort by last_name, then first_name
$sorter = new Sorter();
print_r($sorter->sort($start_data, 'last_name', 'first_name'));
// sort by first_name, then last_name
$sorter = new Sorter();
print_r($sorter->sort($start_data, 'first_name', 'last_name'));
// sort by last_name, then first_name (backwards)
$sorter = new Sorter();
$sorter->backwards = true;
print_r($sorter->sort($start_data, 'last_name', 'first_name'));
// sort numerically by age
$sorter = new Sorter();
$sorter->numeric = true;
print_r($sorter->sort($start_data, 'age'));
İşte uasort kullanarak başka yaklaşım () ve bir anonim geri arama fonksiyonu (kapatma) bulunuyor. Ben düzenli olarak bu işlevi kullandım. PHP 5.3 required - artık bağımlılıkları!
/**
* Sorting array of associative arrays - multiple row sorting using a closure.
* See also: http://the-art-of-web.com/php/sortarray/
*
* @param array $data input-array
* @param string|array $fields array-keys
* @license Public Domain
* @return array
*/
function sortArray( $data, $field ) {
$field = (array) $field;
uasort( $data, function($a, $b) use($field) {
$retval = 0;
foreach( $field as $fieldname ) {
if( $retval == 0 ) $retval = strnatcmp( $a[$fieldname], $b[$fieldname] );
}
return $retval;
} );
return $data;
}
/* example */
$data = array(
array( "firstname" => "Mary", "lastname" => "Johnson", "age" => 25 ),
array( "firstname" => "Amanda", "lastname" => "Miller", "age" => 18 ),
array( "firstname" => "James", "lastname" => "Brown", "age" => 31 ),
array( "firstname" => "Patricia", "lastname" => "Williams", "age" => 7 ),
array( "firstname" => "Michael", "lastname" => "Davis", "age" => 43 ),
array( "firstname" => "Sarah", "lastname" => "Miller", "age" => 24 ),
array( "firstname" => "Patrick", "lastname" => "Miller", "age" => 27 )
);
$data = sortArray( $data, 'age' );
$data = sortArray( $data, array( 'lastname', 'firstname' ) );
Ben çalıştırmak için tablesorter sınıf alabilir önce Shinhan vermişti ne dayalı bir fonksiyonu ile geldi vardı.
function sort2d_bycolumn($array, $column, $method, $has_header)
{
if ($has_header) $header = array_shift($array);
foreach ($array as $key => $row) {
$narray[$key] = $row[$column];
}
array_multisort($narray, $method, $array);
if ($has_header) array_unshift($array, $header);
return $array;
}
İşte benim uygulamasıdır. Ben kategori girişleri dahil bir kategori nesnesi vardı. Ben bir alt-dizi değeri tarafından bu kayıtlar sıralamak istedim. İşte ben bu konuda böyle gitti.
$ In_cat_team_arr ayıklanmamış dizisi nerede
<?php
//sort multidimensional array by $order_in_category
if (count ($in_cat_team_arr) > 0) {
foreach ($in_cat_team_arr as $key => $row) {
$order_in_category[$key] = $row[0];//[0] is $order_in_category
}
array_multisort($order_in_category, SORT_ASC, $in_cat_team_arr);
}
foreach ($in_cat_team_arr as $team_mem) {
//loop through the sorted array here
}
Bu benim için güzel çalışıyor.
Ama bir sorum var. Anahtar adı yerine indeks (örneğin $ row ['my_key_name'] yerine $ row [0]) kullanmak için herhangi bir yolu var mı? Bunu denedim ve şifreli var.
Ben birkaç popüler array_multisort () ve usort () cevaplar çalıştı ve bunların hiçbiri benim için çalıştı. Veri sadece karmakarışık ve kod okunamaz olur. Burada hızlı bir kirli bir çözümdür. UYARI: Kötü niyetli bir sınırlayıcı sonra uğrak geri gelmeyecek emin değilseniz sadece bu kullanın!
Isim, stuff1, stuff2: senin çok dizide her satır gibi görünüyor diyelim:
// Sort by name, pull the other stuff along for the ride
foreach ($names_stuff as $name_stuff) {
// To sort by stuff1, that would be first in the contatenation
$sorted_names[] = $name_stuff[0] .','. name_stuff[1] .','. $name_stuff[2];
}
sort($sorted_names, SORT_STRING);
Geri alfabetik sırayla Eşyalarını ihtiyacınız var?
foreach ($sorted_names as $sorted_name) {
$name_stuff = explode(',',$sorted_name);
// use your $name_stuff[0]
// use your $name_stuff[1]
// ...
}
Evet, o kirli. Ama süper kolay, başınızı patlayabilir yapmaz.