Am CSV de date încărcate într-o matrice multidimensionale. În acest fel, fiecare "randul" este o înregistrare și fiecare "coloana" conține același tip de date. Eu sunt, folosind funcția de mai jos pentru a încărca meu de fișier 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;
}
Am nevoie pentru a fi capabil de a specifica o coloană pentru a sorta astfel încât să se rearanjează rânduri. Unul dintre coloane conține informații actualizate în formatul Y-m-d H:i:s
și aș dori să fie capabil de a sorta cu data cea mai recentă fiind primul rând.
Am 'd dori să adăugați propria mea soluție aici, deoarece oferă caracteristici care alte răspunsuri nu.
În special, avantajele acestei soluții includ:
usort " sau " uasort
).: în timp ce
array_multisort` este convenabil, depinde de crearea de o proiecție a tuturor datelor de intrare înainte de sortare. Acest lucru consumă timp și memorie, și poate fi pur și simplu prohibitiv, dacă setul de date este mare.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
};
}
În această secțiune vă va oferi link-uri de genul asta acest eșantion set de date:
$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'),
);
Funcția make_comparer
acceptă un număr variabil de argumente care definesc fel dorit și returnează o funcție care tu ar trebui să utilizeze ca argument pentru usort " sau " uasort
.
Cel mai simplu caz de utilizare este de a trece în cheia care ai 'd place să folosesc pentru a compara elemente de date. De exemplu, pentru a sorta `$date " de " numele elementului ai face
usort($data, make_comparer('name'));
Cheia poate fi, de asemenea, un număr în cazul în care elementele sunt indexate numeric tablouri. De exemplu, în cauză, acest lucru ar fi
usort($data, make_comparer(0)); // 0 = first numerically indexed column
Puteți specifica mai multe sorta coloanele de trecere parametri suplimentari pentru a make_comparer
. De exemplu, pentru a sorta prin "număr" și apoi de la zero indexate coloana:
usort($data, make_comparer('number', 0));
Mai multe caracteristici avansate sunt disponibile dacă specificați un fel de coloană ca o matrice în loc de un șir de simplu. Această matrice ar trebui să fie indexate numeric, și trebuie să conțină aceste elemente:
0 => the column name to sort on (mandatory)
1 => either SORT_ASC or SORT_DESC (optional)
2 => a projection function (optional)
Las's vedem cum putem folosi aceste caracteristici.
Pentru a sorta după nume descrescătoare:
usort($data, make_comparer(['name', SORT_DESC]));
Pentru a sorta după numărul descendent și apoi de numele descrescătoare:
usort($data, make_comparer(['number', SORT_DESC], ['name', SORT_DESC]));
În unele scenarii posibil să aveți nevoie pentru a sorta de o coloană ale căror valori nu se pretează bine la sortare. "aniversare" coloana în eșantion set de date se potrivește această descriere: nu are sens pentru a compara zile de naștere ca siruri de caractere (pentru că, de exemplu, "01/01/1980" vine înainte "10/10/1970"). În acest caz, vrem să specificați cum să proiect datele reale la o formă care poate fi comparate direct cu cele dorite semantica.
Proiecțiile pot fi specificate ca orice tip de nevărsat: ca siruri de caractere, tablouri, sau funcții anonime. O proiecție se presupune a accepta un argument și de a reveni sale proiectate în formă.
Ar trebui remarcat faptul că în timp ce proiecțiile sunt similare cu cele personalizate funcțiile de comparație folosit cu usortși familia, ei sunt mai simple (ai nevoie doar pentru a converti o valoare la alta) și să profite de toate functionalitatile deja coapte în
make_comparer`.
Las's un fel de exemplu de set de date, fără o proiecție și să vedem ce se întâmplă:
usort($data, make_comparer('birthday'));
Că nu a fost rezultatul dorit. Dar putem folosi date_create
ca o proiecție:
usort($data, make_comparer(['birthday', SORT_ASC, 'date_create']));
Aceasta este ordinea corectă în care ne-am dorit.
Sunt mult mai multe lucruri care proiecțiile se poate realiza. De exemplu, o modalitate rapidă de a obține un caz-insensibil fel este de a utiliza strtolower
ca o proiecție.
Asta a spus, ar trebui să menționăm, de asemenea, că'e mai bine să nu folosească proiecțiile dacă setul de date este mare: în acest caz ar fi mult mai rapid pentru proiect toate datele manual în față și apoi, fără a utiliza o proiecție, deși acest lucru va comerțul s-a intensificat utilizarea de memorie mai rapide fel viteza.
În cele din urmă, aici este un exemplu care utilizează toate caracteristicile: în primul rând felul de numărul descrescătoare, apoi de ziua ascendent:
usort($data, make_comparer(
['number', SORT_DESC],
['birthday', SORT_ASC, 'date_create']
));
Puteți utiliza array_multisort()
Incearca ceva de genul asta:
foreach ($mdarray as $key => $row) {
// replace 0 with the field's index/key
$dates[$key] = $row[0];
}
array_multisort($dates, SORT_DESC, $mdarray);
Pentru PHP >= 5.5.0 doar extract de coloana pentru a sorta prin. Nu este nevoie pentru bucla:
array_multisort(array_column($mdarray, 0), SORT_DESC, $mdarray);
Cu usort. Aici's o soluție generică, pe care le puteți folosi pentru diferite coloane:
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;
}
}
Pentru a sorta după prima coloană:
$sorter = new TableSorter(0); // sort by first column
$mdarray = $sorter->sort($mdarray);
Aici's-o altă abordare, folosind uasort() și un anonim funcție de apel invers (de închidere). Am'am folosit care funcționează în mod regulat. PHP 5.3 necesare – nu mai dependențe!
/**
* 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' ) );
Știu că's 2 ani de când această întrebare a fost întrebat și a răspuns, dar aici's-o altă funcție care sortează un tablou bidimensional. Se acceptă un număr variabil de argumente, permițându-vă pentru a trece în mai mult de o cheie (de exemplu, nume de coloană) pentru a sorta prin. PHP 5.3 necesare.
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;
}
Încercați să-l aici: 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/
Aici este un php4/php5 clasa care va rezolva una sau mai multe domenii:
// 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'));
Înainte de a putea obține TableSorter clasa a rula am venit cu o funcție bazat pe ceea ce Shinhan le-a furnizat.
funcția sort2d_bycolumn($matrice, $coloană $metoda, $has_header) { dacă ($has_header) $header = array_shift($matrice); foreach ($matrice as $cheie => $row) { $narray[$key] = $row[$coloana]; } array_multisort($narray, $metoda, $matrice); dacă ($has_header) array_unshift($matrice, $antet); return $matrice; }
Am incercat de mai multe populare array_multisort() si usort() răspunsuri și nici unul dintre ei a lucrat pentru mine. Datele se încurcă și codul nu poate fi citit. Aici's rapid murdar soluție. AVERTISMENT: utilizați acest lucru Numai dacă te're sigur un rogue delimitator câștigat't întoarce să te bântuie mai târziu!
Las's spun fiecare rând în mai multe matrice arata ca: numele, 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);
Nevoie de lucrurile înapoi în ordine alfabetică?
foreach ($sorted_names as $sorted_name) {
$name_stuff = explode(',',$sorted_name);
// use your $name_stuff[0]
// use your $name_stuff[1]
// ...
}
Da, l's murdare. Dar super-ușor, a câștigat't sa-ti explodeze capul.