TypeScriptによる配列のソート


154

私はtypescriptで遭遇した非常に奇妙な問題を理解しようとしています。これは、インラインブール式を、完全な式ではなく、最初の値のタイプとして処理していました。

したがって、次のような簡単なことを試してみてください。

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

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

それを試してみてください

結果はブール値ではなく数値であるため、パラメーターが呼び出しターゲットのシグニチャーと一致しないことを示すsortメソッドでエラーが発生します。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」が「bob@my.net」未満に対してtrueを返す理由を誰かが説明できますか?例:let myTest =( 'Roy@my.net' <'bob@my.net'); //私にはtrueを返します... :(
— Wallace Howery '21

1
後者の場合には、あなたは数を返します。現在のロケールで文字列を比較するlocaleCompareを()を使用することができます
— neural5torm

(n1,n2)=>n1-n2表現がどのように実行または機能するか説明してください。
— Rahul Chaudhari、

1
@RahulChaudhariは数例では、数値をとる関数だn1とn2、それが返す関数内で、n1-n2いずれかの正の数、ゼロ、または負の数になります。これは、アイテムを切り替える必要があるかどうかをソート操作に伝え、ソートを可能にします。
— フェントン、

それは異なるプロパティを持つ可能性のあるフィルターである可能性があります
— Arvind

24

素晴らしい答えソニー。オブジェクトの配列があり、キーで並べ替える場合は、ほとんど同じですが、これはdate(number)またはtitle(string)の両方で並べ替えることができる例の1つです。

    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]として作成することもできます。より動的な場合は、文字列と数値の差分を保持するだけです。


回答へのコメントは、コメント機能を使用して行う必要があります。
— Nicktar 2017

6
@Nicktarおそらくフォーマットの答えとして投稿されています。しかし、とにかく害はありません
— Wouter Vanherck 2017

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とN1 0 == N2
— セバスチャンStormacq

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)


どうもありがとうございました:)
— 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

_.sortByTypeScriptで再作成しようとしているときに、私はこれを今日書いたので、必要な人には残しておこうと思いました。

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

** ここでgetByKey fnが見つかりました

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.