pengantar
Banyak pengembang JavaScript memiliki pengalaman menyortir data di sisi klien. Sayangnya, perpustakaan yang ada memiliki kekurangan kecil. Tetapi kekurangan ini menambah dan membatasi cara pemrogram berpikir tentang pengurutan. Untuk mengatasi keterbatasan ini, mari kita lihat pengurutan dalam berbagai bahasa. Berbekal pengetahuan ini, kita akan dapat memilih antarmuka yang paling nyaman dan ketat.
Bagaimana semuanya dimulai
Suatu hari musim panas yang cerah, pada sebuah proyek dengan AngularJS, saya ditugasi menambahkan fungsi sortir ke tabel. Dalam hal ini, mungkin ada beberapa kriteria untuk pengurutan sekaligus, dan arah untuk setiap kriteria bisa independen.
Daftar persyaratan:
gunakan banyak ekspresi sebagai kunci untuk menyortir
kemampuan untuk menentukan arah pengurutan secara independen untuk masing-masing tombol
kemampuan untuk menyortir string case insensitive dan locale sensitive
-
Apa yang AngularJS tawarkan untuk kami sortir? filter: dokumentasi orderBy
{{ orderBy_expression | orderBy : expression : reverse : comparator }}
$filter('orderBy')(collection, expression, reverse, comparator)
Example:
<tr ng-repeat="friend in friends | orderBy:'-age'">...</tr>
. , -
, , . , . , ? , , JS, . AngularJS, eval
, . AngularJS JS. , TypeScript . expression
, , . , . , .
, β reverse
. ! , . , .
β comparator
, . , comparator
. localeSensitiveComparator
.
, , TypeScript ? JavaScript , , -.
lodash
lodash
, _.sortBy
, .
var users = [
{ 'user': 'fred', 'age': 48 },
{ 'user': 'barney', 'age': 36 },
{ 'user': 'fred', 'age': 40 },
{ 'user': 'barney', 'age': 34 }
];
_.sortBy(users, [(o) => o.user]);
// => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
_.sortBy(users, ['user', 'age']);
// => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]
, , ? - lodash
, _.orderBy
.
This method is like
_.sortBy
except that it allows specifying the sort orders of the iteratees to sort by.
, . :
// Sort by `user` in ascending order and by `age` in descending order.
_.orderBy(users, ['user', 'age'], ['asc', 'desc']);
// => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
β , . , , .
, _.orderBy
.
Array#sort
JavaScript, Array
sort
. . . , . , , β . . , .
items.sort(function(a, b) {
if (b.salary < a.salary) {
return -1;
}
if (b.salary > a.salary) {
return 1;
}
if (a.id < b.id) {
return -1;
}
if (a.id > b.id) {
return 1;
}
return 0;
});
// , `lodash`
// :
lodash.orderBy(items, ['salary', 'id'], ['desc', 'asc']);
, , . , .
, .
SQL / SEQUEL
, , . , , ! , SQL.
, SQL 1976 , . , , ?
SELECT EMPNO,NAME,SAL
FROM EMP
WHERE DNO 50
ORDER BY EMPNO
SQL , :
SELECT EMPNO,NAME,SAL
FROM EMP
ORDER BY SAL DESC, EMPNO ASC
Haskell Rust
Haskell Rust :
Haskell sortOn:
import Data.Ord (Down)
import Data.Sort (sortOn)
sortOn (\employee -> (Down (salary employee), employee_id employee)) employees
Rust slice::sort_by_key:
use std::cmp::{Reverse};
slice.sort_by_key(|employee| (Reverse(employee.salary), employee.id))
, β (newtype) Down Reverse, . , .
Python
Python list.sort sorted, key
.
sorted(employees, key=lambda employee: (employee.salary, employee.id))
Python, Haskell Rust, , . , , - . , , .
from ord_reverse import Reverse
sorted(employees, key=lambda employee: (Reverse(employee.salary), employee.id))
Java C#
Java Arrays.sort
Comparator
( ). Comparator
, , thenComparing
. reversed
.
Comparator<Employee> comparator = Comparator.comparing(Employee.getSalary).reversed() .thenComparing(Employee.getId); Arrays.sort(array, comparator);
β . ORDER BY SALARY ASC, ID DESC
:
// 1, ,
Comparator<Employee> comparator =
Comparator.comparing(Employee.getSalary)
.thenComparing(Comparator.comparing(Employee.getId).reversed());
// 2, .
// .
Comparator<Employee> comparator =
Comparator.comparing(Employee.getSalary).reversed()
.thenComparing(Employee.getId).reversed();
LINQ Query, SQL, C# Enumerable.OrderBy
Enumerable.OrderByDescending
, Enumerable.ThenBy
Enumerable.ThenByDescending
.
IEnumerable<Employee> query = employees .OrderByDescending(employee => employee.Salary) .ThenBy(employee => employee.Id);
Java . β , : IEnumerable
β 4 , 1 Haskell/Rust/Python. C# , .
, Java, C# . , .
C C++
C qsort:
#include <stdlib.h>
int cmp_employee(const void *p1, const void *p2)
{
const employee *a = (employee*)p1;
const employee *b = (employee*)p2;
if (b->salary < a->salary) {
return -1;
}
if (b->salary > a->salary) {
return 1;
}
if (a->id < b->id) {
return -1;
}
if (a->id > b->id) {
return 1;
}
return 0;
}
/* ... */
qsort(employees, count, sizeof(employee), cmp_employee);
C++ std::sort:
#include <algorithm>
/* ... */
std::sort(employees.begin(), employees.end(), [](const employee &a, const employee &b) {
if (b->salary < a->salary) {
return true;
}
if (b->salary > a->salary) {
return false;
}
return a->id < b->id;
});
C, C++ . C ( , ), C++ β . - , . , C++ .
C C++ . Array#sort
, , .
, Haskell Rust. JavaScript?
JS , , JS . , . ?
sortBy(array, (employee) => [{ reverse: employee.salary }, employee.id]);
JavaScript
, . JavaScript , , Trait
- typeclass
-, , .
:
null
.Maybe
Option
.
, .
NaN
.
, , BigInt JavaScript.
, .
{ reverse: xxx }
,xxx
.Down
/Reverse
{ localeCompare: sss, collator: ccc }
,sss
ccc
. .
.
- , . .
, β : better-cmp
: X?
orderBy: "Inspired by Angular's orderBy filter", . .
thenby: , Java , - .
multisort: ΰ² _ΰ²
if (/[^\(\r\n]*\([^\(\r\n]*\)$/.test(nextKey)) { var indexOfOpenParenthesis = nextKey.indexOf("("); var args = JSON.parse("[" + nextKey.slice(indexOfOpenParenthesis+1, -1) + "]"); nextKey = nextKey.slice(0, indexOfOpenParenthesis); }
, .
.
" " JavaScript .
Solusi JavaScript terbaik yang dapat saya lakukan sekarang diwujudkan dalam pustaka cmp yang lebih baik yang tersedia di npm.