TypeScript сортировка массива


154

Я пытался выяснить очень странную проблему, с которой столкнулся при машинописи. Это относилось к встроенному логическому выражению как к первому типу значения, а не к полному выражению.

Поэтому, если вы попробуете что-то простое, например, следующее:

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

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

Попытайся

Вы получите сообщение об ошибке в вашем методе сортировки, в котором говорится, что параметры не соответствуют ни одной сигнатуре цели вызова, поскольку ваш результат числовой, а не логический. Я предполагаю, что чего-то не хватает, потому что я почти уверен, что n1> n2 - логическое утверждение.

Ответы:


180

Ошибка полностью исправлена.

Как он пытается вам сказать, .sort()принимает функцию, которая возвращает число, а не логическое значение.

Вы должны вернуть отрицательный, если первый элемент меньше; положительный, если он больше, или ноль, если они равны.


56
Вот почему мы используем TypeScript! :-)
— Стивен Чунг

226

чисел

При сортировке чисел вы можете использовать компактное сравнение:

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

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

то есть, -а не <.

Другие типы

Если вы сравниваете что-то еще, вам нужно преобразовать сравнение в число.

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;
});

Объекты

Для объектов вы можете сортировать их по свойствам, помните о приведенной выше информации о возможности сокращения чисел. Приведенный ниже пример работает независимо от типа.

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;
});

Может кто-нибудь объяснить, почему для теста «меньше» Roy@my.net возвращает true для «меньше», чем bob@my.net? например: let myTest = ('Roy@my.net' <'bob@my.net'); // возвращает истину для меня ... :(
— Уоллес Ховери

1
во втором случае вы можете использовать localeCompare () для сравнения строк в текущей локали, которая возвращает число
— neural5torm

Пожалуйста, объясните мне, как (n1,n2)=>n1-n2выражение будет работать или работать .. ??
— Рахул Чаудхари

1
@RahulChaudhari в примере с числами, это функция, которая принимает числа n1и n2, в пределах возвращаемой функции n1-n2, это будет либо положительное число, ноль, либо отрицательное число. Это сообщает операции сортировки, нужно ли переключать элементы или нет, что позволяет сортировать.
— Фентон

Это может быть возможно фильтр с другим proprty
— Arvind

24

Отличный ответ Sohnee. Хотелось бы добавить, что если у вас есть массив объектов, и вы хотите отсортировать по ключу, то это почти то же самое, это пример того, который может сортировать как по дате (число), так и по заголовку (строка):

    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;
    }

Также можно сделать значения внутри переменных n1 [поле] против n2 [поле], если оно более динамичное, просто сохраните различие между строками и числами.


Комментировать комментарии следует с помощью функции комментариев.
— Nicktar

6
@Nicktar Это вероятно отправлено как ответ для форматирования. Но это все равно не приносит вреда
— 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);

Сортировать по некоторому полю:

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 отрицательно, когда n1 <n2, положительно, когда n1> n2, и 0, когда n1 == n2
— Себастьян Стормак

2
Спасибо! Я изменил это для этого: myArray.sort ((a, b): number => {return a.NumberProp - b.NumberProp;});
— Lrodriguez84

10

Сортировать смешанный массив (буквы и цифры)

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)


Большое вам спасибо :)
— Стив


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)


Здравствуйте, добро пожаловать в stackoverflow, stackoverflow.com/help/how-to-answer, пожалуйста, прочитайте эту документацию и предоставьте некоторое описание того, что должно быть сделано.
— Prateik Darji

0

Я написал это сегодня, пытаясь воссоздать _.sortByв TypeScript, и думал, что оставлю его для всех, кто в этом нуждается.

// ** 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
    })
}

Использование:

Он ожидает массив универсального типа T, отсюда приведение к <T extends {}>типу, а также ввод параметра и возвращаемого типа функции сT[]

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

** getByKeyFN найден здесь

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.