TypeScript sắp xếp một mảng


154

Tôi đã cố gắng tìm ra một vấn đề rất lạ mà tôi gặp phải với bản thảo. Nó đã xử lý một biểu thức Boolean nội tuyến như bất kỳ loại giá trị đầu tiên nào thay vì biểu thức hoàn chỉnh.

Vì vậy, nếu bạn thử một cái gì đó đơn giản như sau:

var numericArray:Array<number> = [2,3,4,1,5,8,11];

var sorrtedArray:Array<number> = numericArray.sort((n1,n2)=> n1 > n2);

Thử nó

Bạn sẽ gặp lỗi trên phương thức sắp xếp của mình, cho biết các tham số không khớp với bất kỳ chữ ký nào của mục tiêu cuộc gọi, vì kết quả của bạn là số và không phải là Boolean. Tôi đoán rằng tôi đang thiếu một cái gì đó mặc dù tôi khá chắc chắn n1> n2 là một tuyên bố Boolean.

Câu trả lời:


180

Lỗi hoàn toàn chính xác.

Vì nó đang cố nói với bạn, .sort()lấy một hàm trả về số chứ không phải boolean.

Bạn cần trả về âm nếu mục đầu tiên nhỏ hơn; tích cực nếu nó lớn hơn hoặc bằng 0 nếu chúng bằng nhau.


56
Đó là lý do tại sao chúng tôi sử dụng TypeScript! :-)
Stephen Chung

226

Số

Khi sắp xếp số, bạn có thể sử dụng so sánh nhỏ gọn:

var numericArray: number[] = [2, 3, 4, 1, 5, 8, 11];

var sortedArray: number[] = numericArray.sort((n1,n2) => n1 - n2);

tức -là hơn <.

Các loại khác

Nếu bạn đang so sánh bất cứ điều gì khác, bạn sẽ cần chuyển đổi so sánh thành một số.

var stringArray: string[] = ['AB', 'Z', 'A', 'AC'];

var sortedArray: string[] = stringArray.sort((n1,n2) => {
    if (n1 > n2) {
        return 1;
    }

    if (n1 < n2) {
        return -1;
    }

    return 0;
});

Các đối tượng

Đối với các đối tượng, bạn có thể sắp xếp dựa trên một thuộc tính, ghi nhớ các thông tin trên về việc có thể sử dụng các loại số ngắn. Ví dụ dưới đây hoạt động không phân biệt loại.

var objectArray: { age: number; }[] = [{ age: 10}, { age: 1 }, {age: 5}];

var sortedArray: { age: number; }[] = objectArray.sort((n1,n2) => {
    if (n1.age > n2.age) {
        return 1;
    }

    if (n1.age < n2.age) {
        return -1;
    }

    return 0;
});

Ai đó có thể giải thích lý do tại sao, đối với bài kiểm tra ít hơn, 'Roy@my.net' trả về giá trị thấp hơn 'bob@my.net' không? ví dụ: hãy để myTest = ('Roy@my.net' <'bob@my.net'); // trả về đúng cho tôi ... :(
Wallace Howery

1
trong trường hợp thứ hai, bạn có thể sử dụng localeCompare () để so sánh các chuỗi trong miền địa phương hiện tại, trả về một số
neural5torm

Hãy giải thích cho tôi, Làm thế nào (n1,n2)=>n1-n2biểu thức sẽ thực thi hoặc làm việc .. ??
Rahul Chaudhari

1
@RahulChaudhari trong ví dụ về số, đó là một hàm lấy các số n1n2, trong hàm mà nó trả về n1-n2, sẽ là số dương, số 0 hoặc số âm. Điều này cho biết hoạt động sắp xếp xem các mục cần phải được chuyển đổi hay không, do đó cho phép sắp xếp.
Fenton

nó có thể là bộ lọc có thể với các proprty khác nhau
Arvind

24

Sohnee trả lời tuyệt vời. Muốn thêm rằng nếu bạn có một mảng các đối tượng và bạn muốn sắp xếp theo khóa thì nó gần giống nhau, đây là một ví dụ về một đối tượng có thể sắp xếp theo cả ngày (số) hoặc tiêu đề (chuỗi):

    if (sortBy === 'date') {
        return n1.date - n2.date
    } else {
        if (n1.title > n2.title) {
           return 1;
        }
        if (n1.title < n2.title) {
            return -1;
        }
        return 0;
    }

Cũng có thể làm cho các giá trị bên trong dưới dạng các biến n1 [trường] so với n2 [trường] nếu nó động hơn, chỉ cần giữ khác biệt giữa các chuỗi và số.


Bình luận về câu trả lời nên được thực hiện bằng cách sử dụng chức năng bình luận.
Nicktar

6
@Nicktar Có lẽ nó được đăng dưới dạng câu trả lời cho định dạng. Nhưng dù sao nó cũng không gây hại gì
Wouter Vanherck

11
let numericArray: number[] = [2, 3, 4, 1, 5, 8, 11];

let sortFn = (n1 , n2) => number { return n1 - n2; }

const sortedArray: number[] = numericArray.sort(sortFn);

Sắp xếp theo một số lĩnh vực:

let arr:{key:number}[] = [{key : 2}, {key : 3}, {key : 4}, {key : 1}, {key : 5}, {key : 8}, {key : 11}];

let sortFn2 = (obj1 , obj2) => {key:number} { return obj1.key - obj2.key; }

const sortedArray2:{key:number}[] = arr.sort(sortFn2);

1
n1 - n2 âm khi n1 <n2, dương khi n1> n2 và 0 khi n1 == n2
Sébastien Stormacq

2
Cảm ơn! Tôi đã thay đổi nó cho điều này: myArray.sort ((a, b): number => {return a.NumberProp - b.NumberProp;});
Lrodriguez84

10

Sắp xếp mảng hỗn hợp (bảng chữ cái và số)

function naturalCompare(a, b) {
   var ax = [], bx = [];

   a.replace(/(\d+)|(\D+)/g, function (_, $1, $2) { ax.push([$1 || Infinity, $2 || ""]) });
   b.replace(/(\d+)|(\D+)/g, function (_, $1, $2) { bx.push([$1 || Infinity, $2 || ""]) });

   while (ax.length && bx.length) {
     var an = ax.shift();
     var bn = bx.shift();
     var nn = (an[0] - bn[0]) || an[1].localeCompare(bn[1]);
     if (nn) return nn;
   }

   return ax.length - bx.length;
}

let builds = [ 
    { id: 1, name: 'Build 91'}, 
    { id: 2, name: 'Build 32' }, 
    { id: 3, name: 'Build 13' }, 
    { id: 4, name: 'Build 24' },
    { id: 5, name: 'Build 5' },
    { id: 6, name: 'Build 56' }
]

let sortedBuilds = builds.sort((n1, n2) => {
  return naturalCompare(n1.name, n2.name)
})

console.log('Sorted by name property')
console.log(sortedBuilds)


Cảm ơn bạn rất nhiều :)
Steve


0

function naturalCompare(a, b) {
   var ax = [], bx = [];

   a.replace(/(\d+)|(\D+)/g, function (_, $1, $2) { ax.push([$1 || Infinity, $2 || ""]) });
   b.replace(/(\d+)|(\D+)/g, function (_, $1, $2) { bx.push([$1 || Infinity, $2 || ""]) });

   while (ax.length && bx.length) {
     var an = ax.shift();
     var bn = bx.shift();
     var nn = (an[0] - bn[0]) || an[1].localeCompare(bn[1]);
     if (nn) return nn;
   }

   return ax.length - bx.length;
}

let builds = [ 
    { id: 1, name: 'Build 91'}, 
    { id: 2, name: 'Build 32' }, 
    { id: 3, name: 'Build 13' }, 
    { id: 4, name: 'Build 24' },
    { id: 5, name: 'Build 5' },
    { id: 6, name: 'Build 56' }
]

let sortedBuilds = builds.sort((n1, n2) => {
  return naturalCompare(n1.name, n2.name)
})

console.log('Sorted by name property')
console.log(sortedBuilds)


Xin chào, Chào mừng bạn đến với stackoverflow, stackoverflow.com/help/how-to-answer xin vui lòng đọc tài liệu này và cung cấp một số mô tả những gì nên được thực hiện.
Prateik Darji

0

Tôi đã viết cái này ngày hôm nay trong khi cố gắng tạo lại _.sortBytrong TypeScript và nghĩ rằng tôi sẽ để nó cho bất cứ ai có nhu cầu.

// ** Credits for getKeyValue at the bottom **
export const getKeyValue = <T extends {}, U extends keyof T>(key: U) => (obj: T) => obj[key] 

export const sortBy = <T extends {}>(index: string, list: T[]): T[] => {
    return list.sort((a, b): number => {
        const _a = getKeyValue<keyof T, T>(index)(a)
        const _b = getKeyValue<keyof T, T>(index)(b)
        if (_a < _b) return -1
        if (_a > _b) return 1
        return 0
    })
}

Sử dụng:

Nó mong đợi một mảng có kiểu chung T, do đó, cast cho <T extends {}>, cũng như gõ kiểu trả về tham số và hàm vớiT[]

const x = [{ label: 'anything' }, { label: 'goes'}]
const sorted = sortBy('label', x)

** getByKeyfn tìm thấy ở đây

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.