複数の列で配列をどのように並べ替えますか?


119

多次元配列があります。プライマリアレイは、

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

私がしようとしていることは、配列owner_nameを次に並べ替えることpublication_nameです。私はJavaScriptであなたが持っていることを知っています、あなたはArray.sort()カスタム関数を置くことができます、私の場合、私は持っています:

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

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

これは、ただ一つの列に並べ替えるため、すなわちOWNER_NAME罰金ですが、どのように私は上の並べ替えにそれを修正するかowner_name、その後、publication_name

回答:


166

所有者名が異なる場合は、それらで並べ替えます。それ以外の場合は、タイブレーカーのパブリケーション名を使用します。

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 2番目の属性をソートする方法もわかりません。選択した列の数だけループしない限り..私は正しいですか?例[[A, 10], [J, 15], [A, 5], [J, 5]] => [[A, 10], [A, 5], [J, 15], [J, 5]]
ブラ...

2
@ user26409021-いいえ、そうではありません。最終的には[[A、5]、[A、10]、[J、5]、[J、15]]になります。最初に最初の属性でソートし、それらが同じ場合は2番目の属性でソートします。したがって、あなたの例では、AはJの前に来ます。Aが2つの要素で同じである場合、2番目の属性を使用します。したがって、[A、10]、[A、5]の場合、5は10の前に来るため、順序付けでは[A、5]、[A、10]になります。不足している可能性があるのは、Array.sortを使用すると、並べ替えが完了するまでmysort関数が複数回呼び出されることです。
dcp 2015

3
@ user26409021-Array.sortは配列が適切にソートされるまで必要に応じて関数を呼び出すため、mysortfunction関数にループは必要ありません。mysort関数が担当する唯一のことは、引数aとbが等しいかどうか、aがbより小さいかどうか、またはaがbより大きいかどうかを判断することです。その決定を行うためにループは必要ありません。お役に立てば幸いです。
dcp 2015

58

あなたが探しているのはthenBy.jsだと思います:https//github.com/Teun/thenBy.js

標準のArray.sortを使用できますが、firstBy().thenBy().thenBy()スタイルを使用します。

ここに例を示します


大規模なデータセットのパフォーマンスには注意してください。thenBy呼び出されるたびに、すべての配列項目が再びループされます。
Ray Shan

6
それは間違いなくそうではありません。thenBy()を呼び出すと、前の関数をカプセル化する新しい関数が作成されます。ソート時には、Javascriptを厳密に項目「ループスルー」は、それはありませんでしょう、あなたが何度もそれを渡す関数を呼び出します。thenByを使用しても、呼び出しの数は変わりません。パフォーマンスに関する考慮事項については、github.com
Teun

2
パフォーマンスについて考えてくれてありがとう。おそらく、新しい関数でクロージャーを作成する際のメモリーに関する考慮事項についてメモを追加しますか?
Ray Shan

これを複数の動的に使用する方法は?またはforループで?
Hemil Patel

@ハリーうまく動かない場合は、並べ替えができない例を載せて投稿してください。そうすれば、他の人も学ぶことができます。お手伝いさせていただきます。github.com/Teun/thenBy.js/issues
Teun D

35

文字列である多くのフィールドでソートする良い方法はtoLocaleCompare、とブール演算子を使用すること||です。

何かのようなもの:

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

さらに多くのフィールドでソートしたい場合は、ブール演算子を使用して、returnステートメントからフィールドをチェーンするだけです。


実際のところ、あなたはそれを片付けることができます.reduce()
ekkis

ただし、.localCompare()-1、0、1を返すので、||として機能するとは思わない ブール値に適しています
ekkis 2017

10
@ ekkis、1と-1はどちらも「真実」であるため、これは非常にエレガントなソリューションです。私はこれをやったところです。 sortItems = (a, b) => (a.distance - b.distance) || (a.name - b.name); そして、それは私の不規則なニーズに対する魅力のように機能します。
bstst

1
@bststは(a.name - b.name)必要がない限り評価されないため、より良い方法です。最初に変数を作成すると、不要な場合でも追加の作業が行われます。
アンディ2018

それは事実です、これは必要以上に多くの作業を行いますが、私はそれを重要な領域でのみ変更します。名目上の量のデータをソートするコードの場合、コードの明快さはパフォーマンスより優先されます。
tbranyen

27

SQLスタイルのascとdescの混合オブジェクト配列ソートをキーで行う必要が出てきました。

上記のケネベックの解決策は私がこれを達成するのに役立ちました:

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

使用例:

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

次の結果が得られます。

 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: {  }

ここから印刷機能を使用)

ここにjsbinの例があります。

編集:クリーンアップされ、githubのmksort.jsとして投稿されました


17

これは、あらゆるサイズのアルファソートに便利です。並べ替えるインデックスを引数として順番に渡します。

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

このデータをどこから収集しましたか[["Nilesh"、 "Karmshil"]、["Pranjal"、 "Deka"]、["Susants"、 "Ghosh"]、["Shiv"、 "Shankar"] 、["Javid"、 "Ghosh"]、["Shaher"、 "Banu"]、["Javid"、 "Rashid"]];
defau1t 2013

11

組み込みの比較演算子を使用して、論理またはで目的の並べ替え順序をチェーンすることをお勧めします||

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

作業例:

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


これは私にとってはうまくいきました!理解も簡単。ありがとう!
DanCue

これだよ!!!*****
Fredrik Johansson

8

2つの変数を1つのソートキーに連結して、比較に使用できます。

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はもろいからかもしれません。特定の入力キーでは、区切り文字やその他の区別なしに2つの部分をまとめて変更するだけなので、期待どおりに並べ替えることはできません。アイテムXのvar1とvar2が "foo"と "baz"で、アイテムYのvar1が "foobar"だったとします。ソートされた場合、Xが最初に来るはずですが、この場合は2番目になります。この答えは改善されるかもしれませんが、述べたようにそれはただ安全ではありません。
Peter Hansen、

4

multisotrを見つけました。これは、複数の並べ替えのためのシンプルで強力な小さなライブラリです。ダイナミクスの並べ替え基準でオブジェクトの配列を並べ替える必要がありました:

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>

このライブラリはより強力で、それが私の場合でした。それを試してみてください。


2

私は一緒に働いていました ng-grid APIから返されたレコードの配列で複数の列を並べ替える必要ため、この気の利いた動的なマルチ並べ替え機能を思いつきました。

まず、ng-grid「ngGridSorted」の「イベント」を発生させ、この構造を返し、ソートを記述します。

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

そこで、sortData上記のに基づいて動的にソート関数を生成する関数を作成しました(スクロールバーに心配しないでください。長さは約50行だけです。また、スロップについては申し訳ありません。スクロールバー!):

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

次に、API(results)の結果を次のように並べ替えます。

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

他の誰かが私と同じくらいこの解決策を楽しんでくれることを願っています!ありがとう!


使用されるソートデータの列オプションは何ですか?
Alex Hope O'Connor

2

これを試して:

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

私はlet t = [ [publicationID, publication_name, ownderID, owner_name ], ... ]、owner_name = 3およびpublication_name = 1のインデックスである配列内のデータを想定しています。


2

文字列追加メソッド

値を文字列に追加して文字列を比較するだけで、複数の値で並べ替えることができます。1つのキーから次のキーへの流出を防ぐために、分割キー文字を追加すると便利です。

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

いくつかの仮想DOM h関数合成の出力からメモリプールブロックを表示するときに、同様の問題が発生しました。基本的に私は、世界中のプレーヤーからの結果のスコアリングのような多基準データのソートと同じ問題に直面しました。

多基準の並べ替えは次のとおりです。

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

気にしないと、if-elseの入れ子地獄ですぐに失敗する可能性があります...約束のコールバック地獄のように...

「述語」関数を作成して、代替のどの部分を使用するかを決定する場合はどうでしょうか?述語は単純です:

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

分類テスト(byCountrySize、byAge、byGameType、byScore、byLevel ...)を書き込んだ後、テストに重みを付け(1 = asc、-1 = desc、0 =無効)、配列に入れます、および次のように削減「決定」関数を適用します。

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)

そして出来上がり!独自の基準/ウェイト/オーダーを定義するのはあなた次第です...しかし、あなたはアイデアを得ます。お役に立てれば !

編集:*各列に完全な並べ替え順序があることを確認してください*列の順序間に依存関係がなく、循環依存関係がないことに注意してください

そうでなければ、ソートが不安定になる可能性があります!


1

ES6 イテラブル(blinq)を操作するための私自身のライブラリーは、(とりわけ)簡単なマルチレベルのソートを可能にします

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

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


Stackoverflowへようこそ。あなたが提供した答えに加えて、これが問題を修正する理由と方法の簡単な説明を提供することを検討してください。
jtate

0

sort-helper github上のソースと呼ばれるマイクロライブラリをnpmに公開しました。ヘルパーをインポートして、構文を介して配列メソッドのby比較関数を作成し、列を並べ替えるためのいくつかの方法を使用します。sortitems.sort(by(column, ...otherColumns))

  • することで、キーpersons.sort(by('lastName', 'firstName'))
  • セレクタdates.sort(by(x => x.toISOString()))
  • 降順[3, 2, 4, 1].sort(by(desc(n => n)))[3, 2, 1, 0]
  • 大文字小文字を区別しない['B', 'D', 'c', 'a'].sort(by(ignoreCase(x => x))).join('')'aBcD'

これは、この回答で言及されているnice thenByに似ていますが、一部のユーザーの好みにより、以下の違いがあります。

  • オブジェクト指向よりも機能的なアプローチthenByFluent APIを参照)
  • 構文は少し簡潔でありながら、SQLとほぼ同じように読みやすく、自然です。
  • TypeScriptで完全に実装されており、型の安全性と型の表現力の恩恵を受けています。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.