Làm cách nào để bạn sắp xếp một mảng trên nhiều cột?


119

Tôi có một mảng đa chiều. Mảng chính là một mảng

[publicationID][publication_name][ownderID][owner_name] 

Những gì tôi đang cố gắng làm là sắp xếp mảng theo owner_namevà sau đó theo publication_name. Tôi biết trong JavaScript bạn có Array.sort(), bạn có thể đặt một hàm tùy chỉnh, trong trường hợp của tôi, tôi có:

function mysortfunction(a, b) {
    var x = a[3].toLowerCase();
    var y = b[3].toLowerCase();

    return ((x < y) ? -1 : ((x > y) ? 1 : 0));
}

Điều này là tốt cho chỉ sắp xếp trên một cột, cụ thể là OWNER_NAME, nhưng làm thế nào để sửa đổi nó để sắp xếp trên owner_name, sau đó publication_name?

Câu trả lời:


167

Nếu tên chủ sở hữu khác nhau, hãy sắp xếp theo họ. Nếu không, hãy sử dụng tên xuất bản cho tiebreaker.

function mysortfunction(a, b) {

  var o1 = a[3].toLowerCase();
  var o2 = b[3].toLowerCase();

  var p1 = a[1].toLowerCase();
  var p2 = b[1].toLowerCase();

  if (o1 < o2) return -1;
  if (o1 > o2) return 1;
  if (p1 < p2) return -1;
  if (p1 > p2) return 1;
  return 0;
}

@dcp Tôi không hiểu cách nó cũng có thể sắp xếp thuộc tính thứ hai. Trừ khi bạn lặp nó nhiều như số cột đã chọn .. Tôi có đúng không? ví dụ[[A, 10], [J, 15], [A, 5], [J, 5]] => [[A, 10], [A, 5], [J, 15], [J, 5]]
Bla ...

2
@ user26409021 - Không, không đúng. Cuối cùng nó sẽ là [[A, 5], [A, 10], [J, 5], [J, 15]]. Nó sắp xếp theo thuộc tính đầu tiên trước, và nếu chúng giống nhau, thì nó sắp xếp theo thuộc tính thứ hai. Vì vậy, trong ví dụ của bạn, A sẽ đứng trước J. Trong trường hợp A giống nhau cho hai phần tử, thì nó sẽ sử dụng thuộc tính thứ hai. Vì vậy, Đối với [A, 10], [A, 5], 5 đến trước 10 vì vậy nó sẽ kết thúc bằng [A, 5], [A, 10] cho thứ tự. Điều bạn có thể thiếu là chức năng thần bí được gọi nhiều lần khi bạn sử dụng Array.sort cho đến khi việc sắp xếp hoàn tất.
dcp

3
@ user26409021 - Một vòng lặp không cần thiết trong hàm huyền bí, vì Array.sort sẽ gọi hàm khi cần cho đến khi Mảng được sắp xếp đúng. Điều duy nhất mà hàm bí ẩn chịu trách nhiệm là xác định xem các đối số a và b có bằng nhau hay không, a nhỏ hơn b hay a lớn hơn b. Chúng tôi không cần một vòng lặp để thực hiện quyết tâm đó. Hy vọng rằng sẽ giúp.
dcp

58

Tôi nghĩ những gì bạn đang tìm kiếm sau đó làBy.js: https://github.com/Teun/thenBy.js

Nó cho phép bạn sử dụng Array.sort tiêu chuẩn, nhưng với firstBy().thenBy().thenBy()phong cách.

Một ví dụ có thể được nhìn thấy ở đây .


Hãy cẩn thận với hiệu suất trên các tập dữ liệu lớn. Mỗi lần thenByđược gọi, tất cả các mục của mảng được lặp lại.
Ray Shan

6
Đó chắc chắn không phải là trường hợp. Khi bạn gọi thenBy (), nó sẽ xây dựng một hàm mới đóng gói hàm trước đó. Tại thời điểm sắp xếp, javascript sẽ không "lặp qua" các mục một cách nghiêm ngặt, nhưng nó sẽ gọi hàm bạn chuyển nó nhiều lần. Số lượng cuộc gọi sẽ không thay đổi khi sử dụng thenBy. Để biết một số cân nhắc về hiệu suất, hãy đọc: github.com/Teun/thenBy.js#a-word-on-performance
Teun D

2
Tôi hiểu rồi, tôi đã sai, cảm ơn vì đã suy nghĩ về hiệu suất. Có lẽ thêm một ghi chú về những lưu ý trong bộ nhớ khi tạo các bao đóng với các hàm mới?
Ray Shan

Làm thế nào để sử dụng điều này cho nhiều động sau đó? hay trong vòng lặp for?
Hemil Patel

@Harry Nếu bạn không thể làm cho nó hoạt động, vui lòng đăng vấn đề với ví dụ mà bạn không thể sắp xếp, để những người khác cũng có thể học hỏi. Rất vui được giúp bạn. github.com/Teun/thenBy.js/issues
Teun D

35

Một cách tốt để sắp xếp trên nhiều trường là chuỗi là sử dụng toLocaleComparevà toán tử boolean ||.

Cái gì đó như:

// Sorting record releases by name and then by title.
releases.sort((oldRelease, newRelease) => {
  const compareName = oldRelease.name.localeCompare(newRelease.name);
  const compareTitle = oldRelease.title.localeCompare(newRelease.title);

  return compareName || compareTitle;
})

Nếu bạn muốn sắp xếp trên nhiều trường hơn, bạn có thể đơn giản chuỗi chúng ra khỏi câu lệnh return với nhiều toán tử boolean hơn.


thực tế là, bạn có thể thu dọn nó bằng.reduce()
ekkis 20/02/2017

tuy nhiên, .localCompare()trả về -1, 0, 1 nên tôi không nghĩ rằng giải pháp của bạn sẽ hoạt động như || được tốt cho các phép toán luận
ekkis

10
@ekkis, cả 1 và -1 đều là "sự thật", vì vậy đây là một giải pháp rất thanh lịch. Tôi vừa làm điều này: sortItems = (a, b) => (a.distance - b.distance) || (a.name - b.name); và nó hoạt động như một sự quyến rũ cho những nhu cầu không cầu kỳ của tôi.
bstst

1
@bstst theo cách của bạn tốt hơn, vì nó không đánh giá (a.name - b.name)trừ khi cần thiết. Trước tiên, việc tạo biến thực hiện thêm công việc ngay cả khi nó không cần thiết.
andi

Đó là sự thật, điều này làm nhiều việc hơn mức cần thiết, nhưng tôi sẽ chỉ thay đổi nó ở những khu vực quan trọng. Đối với mã phân loại một lượng dữ liệu danh nghĩa, độ rõ ràng của mã sẽ vượt trội hơn hiệu quả.
tbranyen

27

Do cần phải thực hiện sắp xếp mảng đối tượng hỗn hợp asc và desc theo kiểu SQL theo các phím.

giải pháp của kennebec ở trên đã giúp tôi đạt được điều này:

Array.prototype.keySort = function(keys) {

keys = keys || {};

// via
// /programming/5223/length-of-javascript-object-ie-associative-array
var obLen = function(obj) {
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key))
            size++;
    }
    return size;
};

// avoiding using Object.keys because I guess did it have IE8 issues?
// else var obIx = function(obj, ix){ return Object.keys(obj)[ix]; } or
// whatever
var obIx = function(obj, ix) {
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) {
            if (size == ix)
                return key;
            size++;
        }
    }
    return false;
};

var keySort = function(a, b, d) {
    d = d !== null ? d : 1;
    // a = a.toLowerCase(); // this breaks numbers
    // b = b.toLowerCase();
    if (a == b)
        return 0;
    return a > b ? 1 * d : -1 * d;
};

var KL = obLen(keys);

if (!KL)
    return this.sort(keySort);

for ( var k in keys) {
    // asc unless desc or skip
    keys[k] = 
            keys[k] == 'desc' || keys[k] == -1  ? -1 
          : (keys[k] == 'skip' || keys[k] === 0 ? 0 
          : 1);
}

this.sort(function(a, b) {
    var sorted = 0, ix = 0;

    while (sorted === 0 && ix < KL) {
        var k = obIx(keys, ix);
        if (k) {
            var dir = keys[k];
            sorted = keySort(a[k], b[k], dir);
            ix++;
        }
    }
    return sorted;
});
return this;
};

sử dụng mẫu:

var obja = [
  {USER:"bob",  SCORE:2000, TIME:32,    AGE:16, COUNTRY:"US"},
  {USER:"jane", SCORE:4000, TIME:35,    AGE:16, COUNTRY:"DE"},
  {USER:"tim",  SCORE:1000, TIME:30,    AGE:17, COUNTRY:"UK"},
  {USER:"mary", SCORE:1500, TIME:31,    AGE:19, COUNTRY:"PL"},
  {USER:"joe",  SCORE:2500, TIME:33,    AGE:18, COUNTRY:"US"},
  {USER:"sally",    SCORE:2000, TIME:30,    AGE:16, COUNTRY:"CA"},
  {USER:"yuri", SCORE:3000, TIME:34,    AGE:19, COUNTRY:"RU"},
  {USER:"anita",    SCORE:2500, TIME:32,    AGE:17, COUNTRY:"LV"},
  {USER:"mark", SCORE:2000, TIME:30,    AGE:18, COUNTRY:"DE"},
  {USER:"amy",  SCORE:1500, TIME:29,    AGE:19, COUNTRY:"UK"}
];

var sorto = {
  SCORE:"desc",TIME:"asc", AGE:"asc"
};

obja.keySort(sorto);

mang lại những điều sau:

 0: {     USER: jane;     SCORE: 4000;    TIME: 35;       AGE: 16;    COUNTRY: DE;   }
 1: {     USER: yuri;     SCORE: 3000;    TIME: 34;       AGE: 19;    COUNTRY: RU;   }
 2: {     USER: anita;    SCORE: 2500;    TIME: 32;       AGE: 17;    COUNTRY: LV;   }
 3: {     USER: joe;      SCORE: 2500;    TIME: 33;       AGE: 18;    COUNTRY: US;   }
 4: {     USER: sally;    SCORE: 2000;    TIME: 30;       AGE: 16;    COUNTRY: CA;   }
 5: {     USER: mark;     SCORE: 2000;    TIME: 30;       AGE: 18;    COUNTRY: DE;   }
 6: {     USER: bob;      SCORE: 2000;    TIME: 32;       AGE: 16;    COUNTRY: US;   }
 7: {     USER: amy;      SCORE: 1500;    TIME: 29;       AGE: 19;    COUNTRY: UK;   }
 8: {     USER: mary;     SCORE: 1500;    TIME: 31;       AGE: 19;    COUNTRY: PL;   }
 9: {     USER: tim;      SCORE: 1000;    TIME: 30;       AGE: 17;    COUNTRY: UK;   }
 keySort: {  }

(sử dụng chức năng in từ đây )

đây là một ví dụ về jsbin .

chỉnh sửa: đã được dọn dẹp và đăng dưới dạng mksort.js trên github .


17

Điều này rất tiện lợi cho các loại alpha ở mọi kích cỡ. Chuyển cho nó các chỉ mục bạn muốn sắp xếp theo thứ tự làm đối số.

Array.prototype.deepSortAlpha= function(){
    var itm, L=arguments.length, order=arguments;

    var alphaSort= function(a, b){
        a= a.toLowerCase();
        b= b.toLowerCase();
        if(a== b) return 0;
        return a> b? 1:-1;
    }
    if(!L) return this.sort(alphaSort);

    this.sort(function(a, b){
        var tem= 0,  indx=0;
        while(tem==0 && indx<L){
            itm=order[indx];
            tem= alphaSort(a[itm], b[itm]); 
            indx+=1;        
        }
        return tem;
    });
    return this;
}

var arr= [[ "Nilesh","Karmshil"], ["Pranjal","Deka"], ["Susants","Ghosh"],
["Shiv","Shankar"], ["Javid","Ghosh"], ["Shaher","Banu"], ["Javid","Rashid"]];

arr.deepSortAlpha(1,0);

Tôi có thể biết bạn đã thu thập dữ liệu này từ đâu [["Nilesh", "Karmshil"], ["Pranjal", "Deka"], ["Susants", "Ghosh"], ["Shiv", "Shankar"] , ["Javid", "Ghosh"], ["Shaher", "Banu"], ["Javid", "Rashid"]];
defau1t

11

Tôi khuyên bạn nên sử dụng một trình so sánh tích hợp sẵn và xâu chuỗi thứ tự sắp xếp mong muốn với logic hoặc ||.

function customSort(a, b) {
    return a[3].localeCompare(b[3]) || a[1].localeCompare(b[1]);
}

Ví dụ làm việc:

var array = [
    [0, 'Aluminium', 0, 'Francis'],
    [1, 'Argon', 1, 'Ada'],
    [2, 'Brom', 2, 'John'],
    [3, 'Cadmium', 3, 'Marie'],
    [4, 'Fluor', 3, 'Marie'],
    [5, 'Gold', 1, 'Ada'],
    [6, 'Kupfer', 4, 'Ines'],
    [7, 'Krypton', 4, 'Joe'],
    [8, 'Sauerstoff', 3, 'Marie'],
    [9, 'Zink', 5, 'Max']
];

array.sort(function (a, b) {
    return a[3].localeCompare(b[3]) || a[1].localeCompare(b[1]);
});

document.write('<pre>');
array.forEach(function (a) {
    document.write(JSON.stringify(a) + '<br>');
});


Nó hiệu quả tuyệt vời đối với tôi! Đơn giản để hiểu cũng được. Cảm ơn!
DanCue

Đây là nó!!! *****
Fredrik Johansson

8

Bạn có thể nối 2 biến lại với nhau thành một khóa sắp xếp và sử dụng nó để so sánh.

list.sort(function(a,b){
   var aCat = a.var1 + a.var2;
   var bCat = b.var1 + b.var2;
   return (aCat > bCat ? 1 : aCat < bCat ? -1 : 0);
});

@GustavoRodrigues có lẽ vì nó quá giòn. Nó sẽ không thể sắp xếp theo kiểu mong đợi trên một số phím nhập nhất định vì nó chỉ trộn hai phần lại với nhau mà không có dấu phân cách hoặc sự phân biệt khác. Hãy xem xét nếu var1 và var2 cho mục X là "foo" và "baz", trong khi var1 cho mục Y là "foobar". Khi được sắp xếp X nên đứng đầu nhưng trong trường hợp này nó sẽ đứng thứ hai. Câu trả lời này có thể được cải thiện nhưng như đã nói nó không an toàn.
Peter Hansen

4

Tôi đã tìm thấy nhiều giá trị . Đây là thư viện đơn giản, mạnh mẽ và nhỏ để phân loại nhiều lần. Tôi cần sắp xếp một mảng các đối tượng với tiêu chí sắp xếp động lực học:

const criteria = ['name', 'speciality']
const data = [
  { name: 'Mike', speciality: 'JS', age: 22 },
  { name: 'Tom', speciality: 'Java', age: 30 },
  { name: 'Mike', speciality: 'PHP', age: 40 },
  { name: 'Abby', speciality: 'Design', age: 20 },
]

const sorted = multisort(data, criteria)

console.log(sorted)
<script src="https://cdn.rawgit.com/peterkhayes/multisort/master/multisort.js"></script>

Thư viện này mạnh mẽ hơn, đó là trường hợp của tôi. Thử nó.


2

Tôi đã làm việc với ng-grid và cần sắp xếp nhiều cột trên một mảng bản ghi được trả về từ một API, vì vậy tôi đã nghĩ ra hàm đa sắp xếp động, tiện lợi này.

Trước hết, ng-gridkích hoạt một "sự kiện" cho "ngGridSorted" và chuyển cấu trúc này trở lại, mô tả kiểu:

sortData = {
    columns:    DOM Element,
    directions: [], //Array of string values desc or asc. Each index relating to the same index of fields
    fields:     [], //Array of string values
};

Vì vậy, tôi đã xây dựng một hàm sẽ tự động tạo ra một hàm sắp xếp dựa trên sortDatanhư được hiển thị ở trên ( Đừng sợ thanh cuộn! Nó chỉ dài khoảng 50 dòng! Ngoài ra, tôi xin lỗi về độ nghiêng. Nó ngăn chặn một chiều ngang thanh cuộn! ):

function SortingFunction(sortData)
{
    this.sortData = sortData;

    this.sort = function(a, b)
    {
        var retval = 0;

        if(this.sortData.fields.length)
        {
            var i = 0;

            /*
                Determine if there is a column that both entities (a and b)
                have that are not exactly equal. The first one that we find
                will be the column we sort on. If a valid column is not
                located, then we will return 0 (equal).
            */
            while(  (   !a.hasOwnProperty(this.sortData.fields[i]) 
                    ||  !b.hasOwnProperty(this.sortData.fields[i]) 
                    ||  (a.hasOwnProperty(this.sortData.fields[i]) 
                        && b.hasOwnProperty(this.sortData.fields[i]) 
                        && a[this.sortData.fields[i]] === b[this.sortData.fields[i]])
                    ) && i < this.sortData.fields.length){
                i++;
            }

            if(i < this.sortData.fields.length)
            {
                /*
                    A valid column was located for both entities
                    in the SortData. Now perform the sort.
                */
                if(this.sortData.directions 
                && i < this.sortData.directions.length 
                && this.sortData.directions[i] === 'desc')
                {
                    if(a[this.sortData.fields[i]] > b[this.sortData.fields[i]])
                        retval = -1;
                    else if(a[this.sortData.fields[i]] < b[this.sortData.fields[i]])
                        retval = 1;
                }
                else
                {
                    if(a[this.sortData.fields[i]] < b[this.sortData.fields[i]])
                        retval = -1;
                    else if(a[this.sortData.fields[i]] > b[this.sortData.fields[i]])
                        retval = 1;
                }
            }
        }

        return retval;
    }.bind(this);
}

Sau đó, tôi sắp xếp các kết quả của API ( results) của mình như sau:

results.sort(new SortingFunction(sortData).sort);

Tôi hy vọng ai đó khác cũng thích giải pháp này như tôi! Cảm ơn!


tùy chọn cột trên dữ liệu sắp xếp được sử dụng để làm gì?
Alex Hope O'Connor

2

Thử cái này:

t.sort( (a,b)=> a[3].localeCompare(b[3]) || a[1].localeCompare(b[1]) );

Tôi giả sử rằng dữ liệu của bạn trong mảng let t = [ [publicationID, publication_name, ownderID, owner_name ], ... ]mà chỉ mục của owner_name = 3 và Publishing_name = 1.


2

Phương pháp nối chuỗi

Bạn có thể sắp xếp theo nhiều giá trị đơn giản bằng cách nối các giá trị vào một chuỗi và so sánh các chuỗi. Sẽ rất hữu ích nếu bạn thêm một ký tự khóa phân tách để ngăn dòng chảy từ khóa này sang khóa tiếp theo.

Thí dụ

const arr = [ 
    { a: 1, b: 'a', c: 3 },
    { a: 2, b: 'a', c: 5 },
    { a: 1, b: 'b', c: 4 },
    { a: 2, b: 'a', c: 4 }
]


function sortBy (arr, keys, splitKeyChar='~') {
    return arr.sort((i1,i2) => {
        const sortStr1 = keys.reduce((str, key) => str + splitKeyChar+i1[key], '')
        const sortStr2 = keys.reduce((str, key) => str + splitKeyChar+i2[key], '')
        return sortStr1.localeCompare(sortStr2)
    })
}

console.log(sortBy(arr, ['a', 'b', 'c']))


1
function multiSort() {

    var args =$.makeArray( arguments ),
        sortOrder=1, prop='', aa='',  b='';

    return function (a, b) {

       for (var i=0; i<args.length; i++){

         if(args[i][0]==='-'){
            prop=args[i].substr(1)
            sortOrder=-1
         }
         else{sortOrder=1; prop=args[i]}

         aa = a[prop].toLowerCase()
         bb = b[prop].toLowerCase()

         if (aa < bb) return -1 * sortOrder;
         if (aa > bb) return 1 * sortOrder;

       }

       return 0
    }

}
empArray.sort(multiSort( 'lastname','firstname')) Reverse with '-lastname'

1

Tôi đã gặp sự cố tương tự khi hiển thị các khối nhóm bộ nhớ từ đầu ra của một số thành phần chức năng h DOM ảo. Về cơ bản, tôi phải đối mặt với cùng một vấn đề là sắp xếp dữ liệu đa tiêu chí như kết quả ghi bàn từ những người chơi trên khắp thế giới.

Tôi nhận thấy rằng sắp xếp theo nhiều tiêu chí là:

- sort by the first column
- if equal, sort by the second
- if equal, sort by the third
-  etc... nesting and nesting if-else

Và nếu bạn không quan tâm, bạn có thể thất bại nhanh chóng trong một địa ngục lồng lộn nếu-khác ... giống như địa ngục gọi lại của những lời hứa ...

Còn nếu chúng ta viết một hàm "vị từ" để quyết định xem sử dụng phần thay thế nào thì sao? Vị ngữ chỉ đơn giản là:

// useful for chaining test
const decide = (test, other) => test === 0 ? other : test

Bây giờ sau khi đã viết các bài kiểm tra phân loại của bạn (byCountrySize, byAge, byGameType, byScore, byLevel ...) bất cứ ai cần, bạn có thể cân các bài kiểm tra của mình (1 = asc, -1 = desc, 0 = vô hiệu hóa), đặt chúng vào một mảng và áp dụng chức năng 'quyết định' giảm như sau:

const multisort = (s1, s2) => {
  const bcs = -1 * byCountrySize(s1, s2) // -1 = desc 
  const ba =  1 *byAge(s1, s2)
  const bgt = 0 * byGameType(s1, s2) // 0 = doesn't matter
  const bs = 1 * byScore(s1, s2)
  const bl = -1 * byLevel(s1, s2) // -1 = desc

  // ... other weights and criterias

  // array order matters !
  return [bcs, ba, bgt, bs, bl].reduce((acc, val) => decide(val, acc), 0)
}

// invoke [].sort with custom sort...
scores.sort(multisort)

Và Voila ! Việc xác định tiêu chí / trọng lượng / đơn đặt hàng của riêng bạn là tùy thuộc vào bạn, nhưng bạn có ý tưởng. Hi vọng điêu nay co ich !

CHỈNH SỬA: * đảm bảo rằng có tổng thứ tự sắp xếp trên mỗi cột * lưu ý rằng không có sự phụ thuộc giữa các thứ tự cột và không có sự phụ thuộc vòng tròn

nếu không, việc sắp xếp có thể không ổn định!


1

Thư viện riêng của tôi để làm việc với các tệp lặp ES6 (flashq) cho phép (trong số những thứ khác) dễ dàng phân loại nhiều cấp

const blinq = window.blinq.blinq
// or import { blinq } from 'blinq'
// or const { blinq } = require('blinq')
const dates = [{
    day: 1, month: 10, year: 2000
  },
  {
    day: 1, month: 1, year: 2000
  },
  {
    day: 2, month: 1, year: 2000
  },
  {
    day: 1, month: 1, year: 1999
  },
  {
    day: 1, month: 1, year: 2000
  }
]
const sortedDates = blinq(dates)
  .orderBy(x => x.year)
  .thenBy(x => x.month)
  .thenBy(x => x.day);

console.log(sortedDates.toArray())
// or console.log([...sortedDates])
<script src="https://cdn.jsdelivr.net/npm/blinq@2.0.2"></script>


0

Nguồn từ GitHub

function sortMethodAsc(a, b) {
    return a == b ? 0 : a > b ? 1 : -1;
}

function sortMethodWithDirection(direction) { 
    if (direction === undefined || direction == "asc") {
        return sortMethodAsc;
    } else {
        return function(a, b) {
            return -sortMethodAsc(a, b);
        } 
    }
}

function sortMethodWithDirectionByColumn(columnName, direction){   
    const sortMethod = sortMethodWithDirection(direction)
    return function(a, b){
        return sortMethod(a[columnName], b[columnName]);
    } 
}

function sortMethodWithDirectionMultiColumn(sortArray) {
    //sample of sortArray
    // sortArray = [
    //     { column: "column5", direction: "asc" },
    //     { column: "column3", direction: "desc" }
    // ]
    const sortMethodsForColumn = (sortArray || []).map( item => sortMethodWithDirectionByColumn(item.column, item.direction) );
    return function(a,b) {
        let sorted = 0;
        let index = 0;
        while (sorted === 0 && index < sortMethodsForColumn.length) {
            sorted = sortMethodsForColumn[index++](a,b);
        }
        return sorted;
    }
} 

//=============================================
//=============================================
//=============================================
//test

var data = [
    {"CountryName":"Aruba","CountryCode":"ABW","GNI":280},{
        "CountryName":"Afghanistan","CountryCode":"ABW","GNI":280},{"CountryName":"Angola","CountryCode":"AGO","GNI":280},{"CountryName":"Albania","CountryCode":"ALB","GNI":4320},
        {"CountryName":"Arab World","CountryCode":"ARB","GNI":280},{"CountryName":"United Arab Emirates","CountryCode":"ARE","GNI":39130},
        {"CountryName":"Argentina","CountryCode":"ARG","GNI":13030},{"CountryName":"Armenia","CountryCode":"ARM","GNI":3990},{"CountryName":"American Samoa","CountryCode":"ASM","GNI":280},
        {"CountryName":"Antigua and Barbuda","CountryCode":"ATG","GNI":13810},{"CountryName":"Australia","CountryCode":"AUS","GNI":51360},
        {"CountryName":"Austria","CountryCode":"AUT","GNI":45440},{"CountryName":"Azerbaijan","CountryCode":"AZE","GNI":4080},{"CountryName":"Burundi","CountryCode":"BDI","GNI":280},
        {"CountryName":"Belgium","CountryCode":"BEL","GNI":41790},{"CountryName":"Benin","CountryCode":"BEN","GNI":800},{"CountryName":"Burkina Faso","CountryCode":"BFA","GNI":590},
        {"CountryName":"Bangladesh","CountryCode":"BGD","GNI":1470},{"CountryName":"Bulgaria","CountryCode":"BGR","GNI":7860},{"CountryName":"Bahrain","CountryCode":"BHR","GNI":21150},
        {"CountryName":"Bosnia and Herzegovina","CountryCode":"BIH","GNI":4910},{"CountryName":"Belarus","CountryCode":"BLR","GNI":5280},
        {"CountryName":"Belize","CountryCode":"BLZ","GNI":4390},{"CountryName":"Bolivia","CountryCode":"BOL","GNI":3130},{"CountryName":"Brazil","CountryCode":"BRA","GNI":8600},
        {"CountryName":"Barbados","CountryCode":"BRB","GNI":15270},{"CountryName":"Brunei Darussalam","CountryCode":"BRN","GNI":29600},
        {"CountryName":"Bhutan","CountryCode":"BTN","GNI":2660},{"CountryName":"Botswana","CountryCode":"BWA","GNI":6730},
        {"CountryName":"Central African Republic","CountryCode":"CAF","GNI":390},{"CountryName":"Canada","CountryCode":"CAN","GNI":42870},
        {"CountryName":"Central Europe and the Baltics","CountryCode":"CEB","GNI":13009},{"CountryName":"Switzerland","CountryCode":"CHE","GNI":80560},
        {"CountryName":"Chile","CountryCode":"CHL","GNI":13610},{"CountryName":"China","CountryCode":"CHN","GNI":8690},{"CountryName":"Cote d'Ivoire","CountryCode":"CIV","GNI":1580},
        {"CountryName":"Cameroon","CountryCode":"CMR","GNI":1370},{"CountryName":"Colombia","CountryCode":"COL","GNI":5890},{"CountryName":"Comoros","CountryCode":"COM","GNI":1280},
        {"CountryName":"Cabo Verde","CountryCode":"CPV","GNI":3030},{"CountryName":"Costa Rica","CountryCode":"CRI","GNI":11120},
        {"CountryName":"Caribbean small states","CountryCode":"CSS","GNI":8909},{"CountryName":"Cyprus","CountryCode":"CYP","GNI":23720},
        {"CountryName":"Czech Republic","CountryCode":"CZE","GNI":18160},{"CountryName":"Germany","CountryCode":"DEU","GNI":43490},
        {"CountryName":"Djibouti","CountryCode":"DJI","GNI":1880},{"CountryName":"Dominica","CountryCode":"DMA","GNI":6590},{"CountryName":"Denmark","CountryCode":"DNK","GNI":55220},
        {"CountryName":"Dominican Republic","CountryCode":"DOM","GNI":6630},{"CountryName":"Algeria","CountryCode":"DZA","GNI":3940},
        {"CountryName":"East Asia & Pacific (excluding high income)","CountryCode":"EAP","GNI":6987},{"CountryName":"Early-demographic dividend","CountryCode":"EAR","GNI":3352},
        {"CountryName":"East Asia & Pacific","CountryCode":"EAS","GNI":10171},{"CountryName":"Europe & Central Asia (excluding high income)","CountryCode":"ECA","GNI":7375},
        {"CountryName":"Europe & Central Asia","CountryCode":"ECS","GNI":22656},{"CountryName":"Ecuador","CountryCode":"ECU","GNI":5920},
        {"CountryName":"Euro area","CountryCode":"EMU","GNI":35645},{"CountryName":"Spain","CountryCode":"ESP","GNI":27180},{"CountryName":"Estonia","CountryCode":"EST","GNI":18190},
        {"CountryName":"Ethiopia","CountryCode":"ETH","GNI":740},{"CountryName":"European Union","CountryCode":"EUU","GNI":32784},
        {"CountryName":"Fragile and conflict affected situations","CountryCode":"FCS","GNI":1510},{"CountryName":"Finland","CountryCode":"FIN","GNI":44580},
        {"CountryName":"Fiji","CountryCode":"FJI","GNI":4970},{"CountryName":"France","CountryCode":"FRA","GNI":37970},{"CountryName":"Gabon","CountryCode":"GAB","GNI":6650},
        {"CountryName":"United Kingdom","CountryCode":"GBR","GNI":40530},{"CountryName":"Georgia","CountryCode":"GEO","GNI":3780},{"CountryName":"Ghana","CountryCode":"GHA","GNI":1880},
        {"CountryName":"Guinea","CountryCode":"GIN","GNI":790},{"CountryName":"Guinea-Bissau","CountryCode":"GNB","GNI":660},
        {"CountryName":"Equatorial Guinea","CountryCode":"GNQ","GNI":7050},{"CountryName":"Greece","CountryCode":"GRC","GNI":18090},
        {"CountryName":"Grenada","CountryCode":"GRD","GNI":9180},{"CountryName":"Guatemala","CountryCode":"GTM","GNI":4060},{"CountryName":"Guyana","CountryCode":"GUY","GNI":4500},
        {"CountryName":"High income","CountryCode":"HIC","GNI":40142},{"CountryName":"Honduras","CountryCode":"HND","GNI":2250},{"CountryName":"Heavily indebted poor countries (HIPC)","CountryCode":"HPC","GNI":904},{"CountryName":"Croatia","CountryCode":"HRV","GNI":12570},{"CountryName":"Haiti","CountryCode":"HTI","GNI":760},{"CountryName":"Hungary","CountryCode":"HUN","GNI":12870},{"CountryName":"IBRD only","CountryCode":"IBD","GNI":5745},{"CountryName":"IDA & IBRD total","CountryCode":"IBT","GNI":4620},{"CountryName":"IDA total","CountryCode":"IDA","GNI":1313},{"CountryName":"IDA blend","CountryCode":"IDB","GNI":1791},
        {"CountryName":"Indonesia","CountryCode":"IDN","GNI":3540},{"CountryName":"IDA only","CountryCode":"IDX","GNI":1074},{"CountryName":"India","CountryCode":"IND","GNI":1800},{"CountryName":"Ireland","CountryCode":"IRL","GNI":55290},{"CountryName":"Iraq","CountryCode":"IRQ","GNI":4630},{"CountryName":"Iceland","CountryCode":"ISL","GNI":60830},{"CountryName":"Israel","CountryCode":"ISR","GNI":37270},{"CountryName":"Italy","CountryCode":"ITA","GNI":31020},{"CountryName":"Jamaica","CountryCode":"JAM","GNI":4760},{"CountryName":"Jordan","CountryCode":"JOR","GNI":3980},{"CountryName":"Japan","CountryCode":"JPN","GNI":38550},{"CountryName":"Kazakhstan","CountryCode":"KAZ","GNI":7970},{"CountryName":"Kenya","CountryCode":"KEN","GNI":1460},{"CountryName":"Kyrgyz Republic","CountryCode":"KGZ","GNI":1130},
        {"CountryName":"Cambodia","CountryCode":"KHM","GNI":1230},{"CountryName":"Kiribati","CountryCode":"KIR","GNI":3010},{"CountryName":"St. Kitts and Nevis","CountryCode":"KNA","GNI":16240},{"CountryName":"Kuwait","CountryCode":"KWT","GNI":31430},{"CountryName":"Latin America & Caribbean (excluding high income)","CountryCode":"LAC","GNI":7470},{"CountryName":"Lao PDR","CountryCode":"LAO","GNI":2270},{"CountryName":"Lebanon","CountryCode":"LBN","GNI":8400},{"CountryName":"Liberia","CountryCode":"LBR","GNI":620},{"CountryName":"Libya","CountryCode":"LBY","GNI":5500},{"CountryName":"St. Lucia","CountryCode":"LCA","GNI":8830},{"CountryName":"Latin America & Caribbean","CountryCode":"LCN","GNI":8251},{"CountryName":"Least developed countries: UN classification","CountryCode":"LDC","GNI":1011},{"CountryName":"Low income","CountryCode":"LIC","GNI":774},{"CountryName":"Sri Lanka","CountryCode":"LKA","GNI":3850},{"CountryName":"Lower middle income","CountryCode":"LMC","GNI":2118},{"CountryName":"Low & middle income","CountryCode":"LMY","GNI":4455},{"CountryName":"Lesotho","CountryCode":"LSO","GNI":1210},{"CountryName":"Late-demographic dividend","CountryCode":"LTE","GNI":8518},{"CountryName":"Lithuania","CountryCode":"LTU","GNI":15200},{"CountryName":"Luxembourg","CountryCode":"LUX","GNI":70260},{"CountryName":"Latvia","CountryCode":"LVA","GNI":14740},{"CountryName":"Morocco","CountryCode":"MAR","GNI":2860},{"CountryName":"Moldova","CountryCode":"MDA","GNI":2200},{"CountryName":"Madagascar","CountryCode":"MDG","GNI":400},{"CountryName":"Maldives","CountryCode":"MDV","GNI":9760},
        {"CountryName":"Middle East & North Africa","CountryCode":"MEA","GNI":7236},{"CountryName":"Mexico","CountryCode":"MEX","GNI":8610},{"CountryName":"Marshall Islands","CountryCode":"MHL","GNI":4840},{"CountryName":"Middle income","CountryCode":"MIC","GNI":4942},{"CountryName":"Mali","CountryCode":"MLI","GNI":770},
        {"CountryName":"Malta","CountryCode":"MLT","GNI":24080},{"CountryName":"Myanmar","CountryCode":"MMR","GNI":1210},{"CountryName":"Middle East & North Africa (excluding high income)","CountryCode":"MNA","GNI":3832},{"CountryName":"Montenegro","CountryCode":"MNE","GNI":7400},{"CountryName":"Mongolia","CountryCode":"MNG","GNI":3270},{"CountryName":"Mozambique","CountryCode":"MOZ","GNI":420},{"CountryName":"Mauritania","CountryCode":"MRT","GNI":1100},{"CountryName":"Mauritius","CountryCode":"MUS","GNI":10130},{"CountryName":"Malawi","CountryCode":"MWI","GNI":320},{"CountryName":"Malaysia","CountryCode":"MYS","GNI":9650},{"CountryName":"North America","CountryCode":"NAC","GNI":56721},{"CountryName":"Namibia","CountryCode":"NAM","GNI":4570},{"CountryName":"Niger","CountryCode":"NER","GNI":360},{"CountryName":"Nigeria","CountryCode":"NGA","GNI":2100},
        {"CountryName":"Nicaragua","CountryCode":"NIC","GNI":2130},{"CountryName":"Netherlands","CountryCode":"NLD","GNI":46180},{"CountryName":"Norway","CountryCode":"NOR","GNI":75990},{"CountryName":"Nepal","CountryCode":"NPL","GNI":800},{"CountryName":"Nauru","CountryCode":"NRU","GNI":10220},{"CountryName":"New Zealand","CountryCode":"NZL","GNI":38970},{"CountryName":"OECD members","CountryCode":"OED","GNI":37273},{"CountryName":"Oman","CountryCode":"OMN","GNI":14440},{"CountryName":"Other small states","CountryCode":"OSS","GNI":12199},{"CountryName":"Pakistan","CountryCode":"PAK","GNI":1580},{"CountryName":"Panama","CountryCode":"PAN","GNI":13280},{"CountryName":"Peru","CountryCode":"PER","GNI":5960},{"CountryName":"Philippines","CountryCode":"PHL","GNI":3660},{"CountryName":"Palau","CountryCode":"PLW","GNI":12700},{"CountryName":"Papua New Guinea","CountryCode":"PNG","GNI":2340},{"CountryName":"Poland","CountryCode":"POL","GNI":12730},{"CountryName":"Pre-demographic dividend","CountryCode":"PRE","GNI":1379},{"CountryName":"Portugal","CountryCode":"PRT","GNI":19820},{"CountryName":"Paraguay","CountryCode":"PRY","GNI":5470},{"CountryName":"West Bank and Gaza","CountryCode":"PSE","GNI":3180},{"CountryName":"Pacific island small states","CountryCode":"PSS","GNI":3793},{"CountryName":"Post-demographic dividend","CountryCode":"PST","GNI":41609},{"CountryName":"Qatar","CountryCode":"QAT","GNI":60510},{"CountryName":"Romania","CountryCode":"ROU","GNI":10000},{"CountryName":"Russian Federation","CountryCode":"RUS","GNI":9230},{"CountryName":"Rwanda","CountryCode":"RWA","GNI":720},{"CountryName":"South Asia","CountryCode":"SAS","GNI":1729},{"CountryName":"Saudi Arabia","CountryCode":"SAU","GNI":20090},{"CountryName":"Sudan","CountryCode":"SDN","GNI":2380},{"CountryName":"Senegal","CountryCode":"SEN","GNI":1240},{"CountryName":"Singapore","CountryCode":"SGP","GNI":54530},{"CountryName":"Solomon Islands","CountryCode":"SLB","GNI":1920},{"CountryName":"Sierra Leone","CountryCode":"SLE","GNI":510},{"CountryName":"El Salvador","CountryCode":"SLV","GNI":3560},{"CountryName":"Serbia","CountryCode":"SRB","GNI":5180},{"CountryName":"Sub-Saharan Africa (excluding high income)","CountryCode":"SSA","GNI":1485},{"CountryName":"Sub-Saharan Africa","CountryCode":"SSF","GNI":1486},{"CountryName":"Small states","CountryCode":"SST","GNI":11099},{"CountryName":"Sao Tome and Principe","CountryCode":"STP","GNI":1770},{"CountryName":"Suriname","CountryCode":"SUR","GNI":5150},{"CountryName":"Slovak Republic","CountryCode":"SVK","GNI":16610},{"CountryName":"Slovenia","CountryCode":"SVN","GNI":22000},{"CountryName":"Sweden","CountryCode":"SWE","GNI":52590},{"CountryName":"Eswatini","CountryCode":"SWZ","GNI":2950},{"CountryName":"Seychelles","CountryCode":"SYC","GNI":14170},{"CountryName":"Chad","CountryCode":"TCD","GNI":640},{"CountryName":"East Asia & Pacific (IDA & IBRD countries)","CountryCode":"TEA","GNI":7061},
        {"CountryName":"Europe & Central Asia (IDA & IBRD countries)","CountryCode":"TEC","GNI":7866},{"CountryName":"Togo","CountryCode":"TGO","GNI":610},{"CountryName":"Thailand","CountryCode":"THA","GNI":5950},{"CountryName":"Tajikistan","CountryCode":"TJK","GNI":990},{"CountryName":"Turkmenistan","CountryCode":"TKM","GNI":6380},{"CountryName":"Latin America & the Caribbean (IDA & IBRD countries)","CountryCode":"TLA","GNI":8179},{"CountryName":"Timor-Leste","CountryCode":"TLS","GNI":1790},{"CountryName":"Middle East & North Africa (IDA & IBRD countries)","CountryCode":"TMN","GNI":3839},{"CountryName":"Tonga","CountryCode":"TON","GNI":4010},{"CountryName":"South Asia (IDA & IBRD)","CountryCode":"TSA","GNI":1729},
        {"CountryName":"Sub-Saharan Africa (IDA & IBRD countries)","CountryCode":"TSS","GNI":1486},{"CountryName":"Trinidad and Tobago","CountryCode":"TTO","GNI":15340},{"CountryName":"Tunisia","CountryCode":"TUN","GNI":3490},{"CountryName":"Turkey","CountryCode":"TUR","GNI":10940},{"CountryName":"Tuvalu","CountryCode":"TUV","GNI":4970},{"CountryName":"Tanzania","CountryCode":"TZA","GNI":910},{"CountryName":"Uganda","CountryCode":"UGA","GNI":600},{"CountryName":"Ukraine","CountryCode":"UKR","GNI":2390},{"CountryName":"Upper middle income","CountryCode":"UMC","GNI":8197},{"CountryName":"Uruguay","CountryCode":"URY","GNI":15250},{"CountryName":"United States","CountryCode":"USA","GNI":58270},{"CountryName":"Uzbekistan","CountryCode":"UZB","GNI":2000},{"CountryName":"St. Vincent and the Grenadines","CountryCode":"VCT","GNI":7390},{"CountryName":"Vietnam","CountryCode":"VNM","GNI":2160},{"CountryName":"Vanuatu","CountryCode":"VUT","GNI":2920},{"CountryName":"World","CountryCode":"WLD","GNI":10371},{"CountryName":"Samoa","CountryCode":"WSM","GNI":4090},{"CountryName":"Kosovo","CountryCode":"XKX","GNI":3900},
        {"CountryName":"South Africa","CountryCode":"ZAF","GNI":5430},{"CountryName":"Zambia","CountryCode":"ZMB","GNI":1290},{"CountryName":"Zimbabwe","CountryCode":"ZWE","GNI":1170},
        {"CountryName":"Zimbabwe","CountryCode":"ZWE","GNI":1171}];

    const sortMethod = sortMethodWithDirectionMultiColumn(
        [
            { column: "GNI", direction: "asc" },
            { column: "CountryCode", direction: "desc" }
        ]
    );
    let sortedData = data.sort(sortMethod);  
    
    
    console.log("sorted by: 1)column:GNI-asc, 2)column:CountryCode-desc") 
    console.table(sortedData);
    console.log(sortedData);
    


Chào mừng bạn đến với stackoverflow. Ngoài câu trả lời bạn đã cung cấp, vui lòng xem xét cung cấp giải thích ngắn gọn về lý do và cách điều này khắc phục sự cố.
jtate

0

Tôi vừa xuất bản lên npm một thư viện vi mô có tên là sort-helper ( nguồn trên github ) . Ý tưởng là nhập trình trợ giúp byđể tạo hàm so sánh cho sortphương thức mảng thông qua cú pháp items.sort(by(column, ...otherColumns)), với một số cách để diễn đạt các cột để sắp xếp theo:

  • Bằng cách quan trọng : persons.sort(by('lastName', 'firstName')),
  • Bằng cách chọn : dates.sort(by(x => x.toISOString())),
  • Theo thứ tự giảm dần : [3, 2, 4, 1].sort(by(desc(n => n)))[3, 2, 1, 0],
  • Trường hợp bỏ qua : ['B', 'D', 'c', 'a'].sort(by(ignoreCase(x => x))).join('')'aBcD'.

Nó tương tự như thì tốt đẹpBy đã đề cập trong câu trả lời này nhưng với những khác biệt sau đây có thể phù hợp hơn với hương vị của một số:

  • Một cách tiếp cận nhiều chức năng hơn hướng đối tượng (xem thenByAPI thông thạo) ,
  • Cú pháp ngắn gọn hơn một chút và vẫn dễ đọc, tự nhiên gần giống như SQL.
  • Được triển khai đầy đủ trong TypeScript, để hưởng lợi từ sự an toàn của kiểu và tính rõ ràng của kiểu.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.