Introduction
In data-centric information systems, it is a common way to display data in tabular form. Sorting data is an essential feature. Sort can be divided into sorting by single field and sorting by different sorting directions of multiple fields. Single-field sorting is highly limited and cannot meet the user's needs for changes in data concerns. Multi-field sorting can better make up for this defect.
Multi-field sorting, the implementation method can be divided into back-end implementation and front-end implementation from a large level.
Backend sorting
Back-end implementation sorting can be implemented at the database level or at the application level.
It is very simple to implement multi-field sorting at the database level. Just use the SQL sorting command "Order By" - Order By field1 asc, field2 desc, field3 asc -- ....
The application level refers to the web application layer (the C/S architecture is not discussed here), such as PHP, Java Web, ASP.NET, etc. The application-level implementation is to use back-end service languages such as PHP, Java, and .NET (C#/VB) to sort data. Taking ASP.NET C# as an example, because LINQ in C# has built-in operations on collection types and supports multi-attribute sorting, using LINQ can easily achieve this goal - from f in fos orderby f.Name descending, f.Num assending select f (it can be found that the sort syntax of LINQ is almost exactly the same as that of SQL). If other languages do not have similar support built-in, they are implemented according to sorting algorithms, which is general and has nothing to do with programming languages.
Front-end sorting
In JavaScript, arrays have a sorting method "sort". When an array is a simple array (array elements are simple types - strings, values and booleans), this method can be used to easily achieve the sorting purpose. However, when an array element is a non-simple type, such as an Object of a name/value pair, and you want to sort it in different sorting directions according to the specified attributes, a simple call to the "sort" method cannot achieve this.
Fortunately, the "sort" method reserves a custom sorting interface, which can implement the desired sorting method.
Let's see what the "sort" method of array looks like.
sort function prototype
// Sort the elements of the array in place and return this array. // By default, sort by Unicode code point of the string. Array.prototype.sort([compareFunction]:number); // number: -1 | 0 | 1. // Typical comparison function (sorted ascending order). function compareFunction(item1, item2) {if(item1 > item2) {return 1; // If sorted in descending order, return -1. }else if(item1 === item2) {return 0;}else {return -1; // If sorted in descending order, return 1. }}Note: If the compareFunction is not specified, the elements are converted into characters of the string and sorted in Unicode bit order. For example, "Cherry" will be arranged before "banana". When sorting numbers, 9 will appear before 80 because they will be converted to strings first, and "80" is ahead of "9".
•If compareFunction(a, b) is less than 0, then a will be arranged before b;
•If compareFunction(a, b) is equal to 0, a and b
The relative position remains unchanged. Note: ECMAScript standards do not guarantee this behavior, and not all browsers will comply with it (for example, Mozilla in 2003
versions before 2019);
•If compareFunction(a, b) is greater than 0, b will be arranged before a.
•compareFunction(a, b) must always return the same comparison result to the same input, otherwise the sorted result will be uncertain.
Note: The sorting results obtained by the above rules are in ascending order. If you want to get a descending result, you will return a result less than 0 when the comparison result is greater than 0. If the comparison result is less than 0, you can return a result greater than 0.
To implement multi-attribute sorting, the key is to compare the implementation of functions. According to the above rules, the ordering of multiple attributes in different directions is implemented, and the size relationship between the two comparison items is still returned.
So how to determine the size relationship of many attribute objects? This can be done in two steps.
The first step is to record the results obtained by comparing the two sorting items according to their sorting attributes and directions.
var propOrders = { "prop1":"asc", "prop2":"desc", "prop3":"asc"};function cmp(item1, item2, propOrders) {var cps = []; // Used to record the comparison results of each sorting attribute, -1 | 0 | 1 . var isAsc = true; // Sort direction. for(var p in propOrders) {isAsc = propOrders[p] === "asc";if(item1[p] > item2[p]) {cps.push(isAsc ? 1 : -1);break; // You can jump out of the loop, because here you already know that item1 is "greater than item2". } else if(item1[p] === item2[p]) {cps.push(0);} else {cps.push(isAsc ? -1 : 1);break; // You can jump out of the loop, item1 "less than" item2. } } /*...*/}The second step is to comprehensively judge the final size relationship of the two comparison terms based on the comparison results of each sorting attribute.
/* ... */for(var j = 0; j < cps.length; j++) {if(cps[j] === 1 || cps[j] === -1) {return cps[j];}}return 0;With the above idea, it is easy to implement the entire comparison function. Here is the complete JavaScript code for the comparison function:
Comparison function
function SortByProps(item1, item2) {"use strict";var props = [];for (var _i = 2; _i < arguments.length; _i++) {props[_i - 2] = arguments[_i];}var cps = []; // Store the results of the sorting attribute comparison. // If the sorting attribute is not specified, sort it in ascending order of all attributes. var asc = true;if (props.length < 1) {for (var p in item1) {if (item1[p] > item2[p]) {cps.push(1);break; // If greater than, the loop will break out. } else if (item1[p] === item2[p]) {cps.push(0);} else {cps.push(-1);break; // If it is less than, the loop will jump out. }}} else {for (var i = 0; i < props.length; i++) {var prop = props[i];for (var o in prop) {asc = prop[o] === "asc";if (item1[o] > item2[o]) {cps.push(asc ? 1 : -1);break; // If greater than, the loop will break out. } else if (item1[o] === item2[o]) {cps.push(0);} else {cps.push(asc ? -1 : 1);break; // If it is less than, the loop will jump out. }}}} for (var j = 0; j < cps.length; j++) {if (cps[j] === 1 || cps[j] === -1) {return cps[j];}}return 0; }Test cases
// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ propOrders);});console.log(items);}function testAsc() {test({ "name": "asc", "value": "asc" });}function testDesc() {test({ "name": "desc", "value": "desc" });}function testAscDesc() {test({ "name": "asc", "value": "desc" });}function testDescAsc() {test({ "name": "desc", "value": "asc" });} TypeScript code/**** Sort direction. */type Direct = "asc" | "desc";/**** Sort attribute. ** ** @interface IPropertyOrder*/interface IPropertyOrder { [name: string] : Direct;}/**** Simple name/value object. ** ** @interface ISimpleObject*/interface ISimpleObject {[name: string] : string | number | boolean;}/**** Sort simple name/value objects according to the specified attribute and sorting direction (according to the sorting attribute and sorting direction, ** compares the two items in turn and returns the value representing the sorting position). ** ** @template T Simple name/value object. ** @param {T} item1 Sort comparison item 1. ** @param {T} item2 Sort by comparison item 2. ** @param {...IPropertyOrder[]} props sort property. ** @returns If item 1 is greater than item 2, return 1, if item 1 is equal to item 2, return 0, otherwise return -1. */function SortByProps<T extends ISimpleObject>(item1: T, item2: T, ...props: IPropertyOrder[]) {"use strict";var cps: Array<number> = []; // Stores the results of the sorting attribute comparison. // If the sorting attribute is not specified, sort it in ascending order of all attributes. var asc = true;if (props.length < 1) {for (var p in item1) {if (item1[p] > item2[p]) {cps.push(1);break; // If greater than, the loop will break out. } else if (item1[p] === item2[p]) {cps.push(0);} else {cps.push(-1);break; // If it is less than, the loop will jump out. }}} else { // Sort by specified attributes and lifting directions. for (var i = 0; i < props.length; i++) {var prop = props[i];for (var o in prop) {asc = prop[o] === "asc";if (item1[o] > item2[o]) {cps.push(asc ? 1 : -1);break; // If greater than, the loop will break out. } else if (item1[o] === item2[o]) {cps.push(0);} else {cps.push(asc ? -1 : 1);break; // If it is less than, the loop will jump out. }}}} for (var j = 0; j < cps.length; j++) {if (cps[j] === 1 || cps[j] === -1) {return cps[j];}}return 0; }Use scenarios and limitations
Using JavaScript to implement multi-attribute sorting on the front end reduces requests to the server side and reduces computing pressure on the server side, but it is only suitable for situations where only local data needs to be sorted. If you need to sort the entire dataset in multiple attributes, it will eventually be done at the server-side database level.
The above is the full description of how JavaScript object arrays are sorted by the specified attributes and sorting directions that the editor introduced to you. I hope they will be helpful to you. If you have any questions, please leave me a message and the editor will reply to you in time. Thank you very much for your support to Wulin.com website!