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是一个布尔语句。

Answers:


180

该错误是完全正确的。

正如它试图告诉您的那样,.sort()它采用了一个返回数字而不是布尔值的函数。

如果第一项较小,则需要返回负数。如果较大,则为正;如果相等,则为零。


56
这就是为什么我们使用TypeScript!:-)
Stephen Chung

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”返回的真值小于“ bob@my.net”吗?例如:let myTest =('Roy@my.net'<'bob@my.net'); //对我来说返回true ... :(
华莱士·霍瑞

1
在第二种情况下,您可以使用localeCompare()比较当前语言环境中的字符串,该字符串返回一个数字
Neuro5torm

请向我解释,(n1,n2)=>n1-n2表达式将如何执行或工作。
拉胡尔(Rahul Chaudhari)

1
@RahulChaudhari在数字示例中,它是一个接受数字的函数,n1并且n2在返回的函数中n1-n2,它可以是正数,零或负数。这告诉分类操作是否需要切换项目,从而可以进行分类。
Fenton

它可能是具有不同属性的过滤器
Arvind

24

很好的答案,苏妮。还要补充一点,如果您有一个对象数组,并且希望按键排序,则其几乎相同,这是一个可以同时按日期(数字)或标题(字符串)进行排序的示例:

    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 [field]与n2 [field]设置在内,只需保留字符串和数字之间的差异即可。


对答案的评论应使用评论功能完成。
尼克塔尔'17

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,正当n 1> n 2和0 N1 N2 ==时
塞巴斯蒂安Stormacq

2
谢谢!我为此进行了更改:myArray.sort((a,b):number => {return a.NumberProp-b.NumberProp;});
Lrodriguez84 '18

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)


非常感谢您:)
史蒂夫(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)


您好,欢迎来到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在这里找到

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.