[英]Lodash sort collection based on external array
我有一個帶鍵的數組,如下所示:
['asdf12','39342aa','12399','129asg',...]
以及在每個對象中都有這些鍵的集合,如下所示:
[{guid: '39342aa', name: 'John'},{guid: '129asg', name: 'Mary'}, ... ]
有沒有一種根據第一個數組中鍵的順序對集合進行排序的快速方法?
var sortedCollection = _.sortBy(collection, function(item){
return firstArray.indexOf(item.guid)
});
如果您想將不匹配的元素放在 sortedCollection 的末尾而不是開頭,這里只是對已接受答案的簡單添加:
const last = collection.length;
var sortedCollection = _.sortBy(collection, function(item) {
return firstArray.indexOf(item.guid) !== -1? firstArray.indexOf(item.guid) : last;
});
輸入:
var data1 = ['129asg', '39342aa'];
var data2 = [{
guid: '39342aa',
name: 'John'
}, {
guid: '129asg',
name: 'Mary'
}];
首先創建一個索引對象,用_.reduce
,像這樣
var indexObject = _.reduce(data2, function(result, currentObject) { result[currentObject.guid] = currentObject; return result; }, {});
然后map
與來自所述對象的第一陣列的項indexObject
,像這樣
console.log(_.map(data1, function(currentGUID) { return indexObject[currentGUID] }));
輸出
[ { guid: '129asg', name: 'Mary' },
{ guid: '39342aa', name: 'John' } ]
注意:如果您想對這么多對象進行排序,這種方法將非常有效,因為它會減少在第二個數組中的線性查找,這將使整個邏輯以 O(M * N) 的時間復雜度運行。
您可以使用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
構建一個新collection
。 源集合已使用indexBy()
轉換為對象。 你這樣做是為了 at() 對它的每個ids
都有基於密鑰的訪問。
這是有效和干凈的方式:
(導入 lodash identity
和sortBy
):
TS :
function sortByArray<T, U>({ source, by, sourceTransformer = identity }: { source: T[]; by: U[]; sourceTransformer?: (item: T) => U }) {
const indexesByElements = new Map(by.map((item, idx) => [item, idx]));
const orderedResult = sortBy(source, (p) => indexesByElements.get(sourceTransformer(p)));
return orderedResult;
}
或者在JS 中:
function sortByArray({ source, by, sourceTransformer = _.identity }) {
const indexesByElements = new Map(by.map((item, idx) => [item, idx]));
const orderedResult = _.sortBy(source, (p) => indexesByElements.get(sourceTransformer(p)));
return orderedResult;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.