我有一个带有如下键的数组:
['asdf12','39342aa','12399','129asg',...]
并且集合中每个对象都具有这些键,如下所示:
[{guid: '39342aa', name: 'John'},{guid: '129asg', name: 'Mary'}, ... ]
有没有一种快速的方法根据第一个数组中键的顺序对集合进行排序?
我有一个带有如下键的数组:
['asdf12','39342aa','12399','129asg',...]
并且集合中每个对象都具有这些键,如下所示:
[{guid: '39342aa', name: 'John'},{guid: '129asg', name: 'Mary'}, ... ]
有没有一种快速的方法根据第一个数组中键的顺序对集合进行排序?
var sortedCollection = _.sortBy(collection, function(item){
return firstArray.indexOf(item.guid)
});
const index = firstArray.indexOf(item.guid);
return index === -1 ? Infinity : index;
});` - sloreti这里只是对已接受答案进行简单补充,以防您希望将未匹配的元素放在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)的时间复杂度运行。
这是高效且简洁的方法:
(引入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;
}
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;
}
你可以使用 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()
对于每个id
都具有基于键的访问。