web-dev-qa-db-ja.com

外部配列に基づくLodashソートコレクション

私は次のようなキーを持つ配列を持っています:

['asdf12','39342aa','12399','129asg',...] 

そして、次のように各オブジェクトにこれらのキーを持つコレクション:

[{guid: '39342aa', name: 'John'},{guid: '129asg', name: 'Mary'}, ... ]

最初の配列のキーの順序に基づいてコレクションを並べ替える高速な方法はありますか?

20
silintzir
var sortedCollection = _.sortBy(collection, function(item){
  return firstArray.indexOf(item.guid)
});
41
idbehold

入力:

var data1 = ['129asg', '39342aa'];
var data2 = [{
    guid: '39342aa',
    name: 'John'
}, {
    guid: '129asg',
    name: 'Mary'
}];
  1. まず、次のように_.reduceを使用してインデックスオブジェクトを作成します

    var indexObject = _.reduce(data2, function(result, currentObject) {
        result[currentObject.guid] = currentObject;
        return result;
    }, {});
    
  2. そして、次のように、mapからのオブジェクトを含む最初の配列のアイテムをindexObjectします。

    console.log(_.map(data1, function(currentGUID) {
        return indexObject[currentGUID]
    }));
    

出力

[ { guid: '129asg', name: 'Mary' },
  { guid: '39342aa', name: 'John' } ]

注:このメソッドは、非常に多くのオブジェクトを並べ替える場合に非常に効率的です。これにより、ロジック全体がO(M * N)で実行される2番目の配列の線形ルックアップが削減されるためです。 )時間の複雑さ。

6
thefourtheye

indexBy() および at() を使用して、コレクションを並べ替えることができます。利点は、その簡潔なコードとパフォーマンスです。ここでsortBy()を使用するとうまくいきますが、外部配列はすでにソートされています:

_var ids = [ 'cbdbac14', 'cf3526e2', '189af064' ];

var collection = [
    { guid: '189af064', name: 'John' },
    { guid: 'cf3526e2', name: 'Julie' },
    { guid: 'cbdbac14', name: 'James' }
];

_(collection)
    .indexBy('guid')
    .at(ids)
    .pluck('name')
    .value();
// → [ 'James', 'Julie', 'John' ]
_

at()を使用すると、ソートされた外部コレクションを反復処理して、ソースcollectionから新しいコレクションを構築できます。ソースコレクションは、indexBy()を使用してオブジェクトに変換されています。これを行うには、at()がidsのそれぞれに対してキーベースのアクセス権を持ちます。

2
Adam Boduch

一致しない要素をsortedCollectionの最初ではなく最後に配置したい場合に備えて、受け入れられた回答に簡単に追加します。

const last = collection.length;

var sortedCollection = _.sortBy(collection, function(item) {
  return firstArray.indexOf(item.guid) !== -1? firstArray.indexOf(item.guid) : last;
});
2
Alvaro