Saya telah CSV data dimuat ke dalam sebuah array multidimensi. Dengan cara ini masing-masing "baris" adalah catatan dan masing-masing "kolom" berisi satu jenis data yang sama. Saya menggunakan fungsi di bawah ini untuk memuat file CSV.
function f_parse_csv($file, $longest, $delimiter)
{
$mdarray = array();
$file = fopen($file, "r");
while ($line = fgetcsv($file, $longest, $delimiter))
{
array_push($mdarray, $line);
}
fclose($file);
return $mdarray;
}
Aku harus mampu untuk menentukan kolom untuk mengurutkan sehingga menata kembali baris. Salah satu kolom yang berisi informasi tanggal dalam format Y-m-d H:i:s
dan aku ingin menjadi mampu memilah dengan tanggal terakhir menjadi baris pertama.
I 'd ingin menambahkan saya sendiri solusi di sini, karena menawarkan fitur-fitur yang lain jawaban tidak.
Secara khusus, keuntungan dari solusi ini meliputi:
DateTime
contoh).usort
atau uasort
).array_multisort
: sementara array_multisort
lebih nyaman, hal ini tergantung pada menciptakan sebuah proyeksi dari semua input data sebelum sorting. Ini membutuhkan waktu dan memori, dan mungkin akan cukup mahal jika data set yang besar.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
};
}
Seluruh bagian ini saya akan memberikan link yang semacam ini contoh data set:
$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'),
);
Fungsi make_comparer
menerima sejumlah variabel argumen yang menentukan jenis dan mengembalikan fungsi yang anda diharapkan untuk digunakan sebagai argumen untuk usort
atau uasort
.
Yang paling sederhana menggunakan kasus ini untuk lulus dalam kunci yang anda 'd digunakan untuk membandingkan data item. Misalnya, untuk semacam $data
oleh nama
item yang anda akan lakukan
usort($data, make_comparer('name'));
Kunci juga dapat menjadi nomor satu jika barang numerik array diindeks. Misalnya dalam pertanyaan, ini akan menjadi
usort($data, make_comparer(0)); // 0 = first numerically indexed column
Anda dapat menentukan beberapa jenis kolom dengan melewatkan parameter tambahan untuk make_comparer
. Misalnya, untuk mengurutkan berdasarkan "nomor" dan kemudian oleh-nol kolom:
usort($data, make_comparer('number', 0));
Lebih banyak fitur canggih yang tersedia jika anda menentukan jenis kolom sebagai array bukan sebuah string sederhana. Array ini harus diindeks secara numerik, dan harus berisi barang-barang ini:
0 => the column name to sort on (mandatory)
1 => either SORT_ASC or SORT_DESC (optional)
2 => a projection function (optional)
Let's melihat bagaimana kita dapat menggunakan fitur ini.
Untuk mengurutkan berdasarkan nama descending:
usort($data, make_comparer(['name', SORT_DESC]));
Untuk mengurutkan berdasarkan jumlah menurun dan kemudian dengan nama turun:
usort($data, make_comparer(['number', SORT_DESC], ['name', SORT_DESC]));
Dalam beberapa skenario anda mungkin perlu untuk mengurutkan berdasarkan kolom dan nilai-nilai yang tidak meminjamkan baik untuk menyortir. "ulang tahun" kolom pada data sampel yang ditetapkan sesuai dengan deskripsi ini: itu tidak masuk akal untuk membandingkan ulang tahun sebagai string (karena misalnya "01/01/1980" sebelum "10/10/1970"). Dalam hal ini kami ingin untuk menentukan bagaimana untuk proyek data aktual dengan bentuk yang bisa dapat dibandingkan secara langsung dengan yang diinginkan semantik.
Proyeksi dapat ditetapkan sebagai jenis callable: seperti string, array, atau fungsi anonim. Proyeksi ini diasumsikan untuk menerima satu argumen dan kembali diproyeksikan bentuk.
Perlu dicatat bahwa sementara proyeksi mirip dengan custom perbandingan fungsi-fungsi yang digunakan dengan usort
dan keluarga, mereka sederhana (anda hanya perlu untuk mengkonversi nilai satu sama lain) dan mengambil keuntungan dari semua fungsi yang sudah dipanggang ke make_comparer
.
Let's mengurutkan data contoh set tanpa proyeksi dan lihat apa yang terjadi:
usort($data, make_comparer('birthday'));
Itu bukan hasil yang diinginkan. Tapi kita dapat menggunakan date_create
sebagai proyeksi:
usort($data, make_comparer(['birthday', SORT_ASC, 'date_create']));
Ini adalah urutan yang benar yang kita inginkan.
Ada banyak hal yang proyeksi dapat mencapai. Misalnya, cara yang cepat untuk mendapatkan kasus-sensitif semacam ini adalah untuk menggunakan strtolower
sebagai proyeksi.
Yang mengatakan, saya juga harus menyebutkan bahwa itu's lebih baik untuk tidak menggunakan proyeksi jika anda set data yang besar: dalam hal itu akan menjadi jauh lebih cepat untuk memproyeksikan semua data anda secara manual ke depan dan kemudian mengurutkan tanpa menggunakan proyeksi, meskipun demikian akan perdagangan peningkatan penggunaan memori yang lebih cepat semacam kecepatan.
Akhirnya, di sini adalah contoh yang menggunakan semua fitur: pertama jenis dengan jumlah menurun, maka dengan ulang tahun ascending:
usort($data, make_comparer(
['number', SORT_DESC],
['birthday', SORT_ASC, 'date_create']
));
Anda dapat menggunakan array_multisort()
Mencoba sesuatu seperti ini:
foreach ($mdarray as $key => $row) {
// replace 0 with the field's index/key
$dates[$key] = $row[0];
}
array_multisort($dates, SORT_DESC, $mdarray);
Untuk PHP >= 5.5.0 hanya mengekstrak kolom untuk mengurutkan berdasarkan. Tidak perlu untuk loop:
array_multisort(array_column($mdarray, 0), SORT_DESC, $mdarray);
Dengan usort. Berikut ini's solusi yang umum, yang dapat anda gunakan untuk kolom yang berbeda:
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;
}
}
Untuk mengurutkan berdasarkan kolom pertama:
$sorter = new TableSorter(0); // sort by first column
$mdarray = $sorter->sort($mdarray);
Berikut ini's pendekatan lain menggunakan uasort() dan anonim fungsi callback (penutupan). I've digunakan fungsi itu secara teratur. PHP 5.3 diperlukan – tidak ada lagi ketergantungan!
/**
* 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' ) );
Aku tahu itu's 2 tahun sejak pertanyaan ini diajukan dan dijawab, tapi di sini's fungsi lain yang macam array dua dimensi. Ia menerima sejumlah variabel argumen, yang memungkinkan anda untuk lulus di lebih dari satu key (yaitu kolom nama) untuk mengurutkan berdasarkan. PHP 5.3 diperlukan.
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;
}
Cobalah hal berikut ini: http://www.exorithm.com/algorithm/view/sort_multi_array
function cmp($a, $b)
{
$p1 = $a['price'];
$p2 = $b['price'];
return (float)$p1 > (float)$p2;
}
uasort($my_array, "cmp");
http://qaify.com/sort-an-array-of-associative-arrays-by-value-of-given-key-in-php/
Berikut ini adalah php4/php5 kelas yang akan memilah satu atau lebih bidang-bidang:
// 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'));
Sebelum aku bisa mendapatkan TableSorter kelas untuk menjalankan saya telah datang dengan fungsi yang didasarkan pada apa yang Shinhan telah disediakan.
fungsi sort2d_bycolumn($array, $kolom, $metode $has_header)
{
if ($has_header) $header = array_shift($array);
foreach ($array as $key => $row) {
$narray[$key] = $row[$kolom];
}
array_multisort($narray, $metode, $array);
if ($has_header) array_unshift($array, $header);
kembali $array;
}
Aku mencoba beberapa tempat array_multisort() dan usort() jawaban dan tidak satupun dari mereka bekerja untuk saya. Data hanya akan campur aduk dan kode terbaca. Berikut ini's cepat kotor solusi. PERINGATAN: Hanya gunakan ini jika anda're yakin nakal pembatas won't datang kembali untuk menghantui anda nanti!
Let's mengatakan setiap baris dalam array multi terlihat seperti: nama, stuff1, stuff2:
// 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);
Perlu anda kembali hal-hal dalam urutan abjad?
foreach ($sorted_names as $sorted_name) {
$name_stuff = explode(',',$sorted_name);
// use your $name_stuff[0]
// use your $name_stuff[1]
// ...
}
Ya, itu's kotor. Tapi super mudah, tidak't membuat kepala anda meledak.