Javascript JS使用lodash根据对象值对对象数组进行排序
我的结构如下:Javascript JS使用lodash根据对象值对对象数组进行排序,javascript,arrays,sorting,object,Javascript,Arrays,Sorting,Object,我的结构如下: let drives = [ {id: 1, moves:[ {moveId: 1, difference: 1}, {moveId: 2, difference: 2}] }, {id: 2, moves:[ {moveId: 1, difference: -2}] }, {id: 3, moves:[ {moveId: 1, difference: 5},
let drives = [
{id: 1, moves:[
{moveId: 1, difference: 1},
{moveId: 2, difference: 2}]
},
{id: 2, moves:[
{moveId: 1, difference: -2}]
},
{id: 3, moves:[
{moveId: 1, difference: 5},
{moveId: 2, difference: 2},
{moveId: 3, difference: 4}]
},
{id: 4, moves:[
{moveId: 1, difference: 6}]
}
]
现在我想根据移动的差异对驱动器阵列进行排序。结果应该是这样的(取决于排序顺序)
我试着用lodash用这个代码做这个
_.orderBy(drives, 'moves.difference', 'asc');
但这似乎毫无作用。
有人知道如何处理这个问题吗?你的问题似乎要分两部分来解决。对于第一部分,首先对它们自己的数组进行排序,因此答案如下
let驱动器=[
{id:1,移动:[
{moveId:1,差分:1},
{moveId:2,差分:2}]
},
{id:2,移动:[
{moveId:1,差:-2}]
},
{id:3,移动:[
{moveId:1,差分:5},
{moveId:2,difference:2},
{moveId:3,差分:4}]
}
]
drives.forEach(x=>{
x、 移动.排序(函数(a,b){
返回a.差异-b.差异;
});
});
驱动器。排序(功能(a、b){
返回a.moves[0]。差异-b.moves[0]。差异;
});
控制台日志(驱动器)代码>您可以排序两次。首先,对移动
数组进行排序。一旦所有移动
数组被排序。然后根据第一个索引处的差异值进行排序
let drives=[{id:1,moves:[{moveId:1,difference:1},{moveId:2,difference:2}]},{id:2,moves:[{moveId:1,difference:3},{moveId:1,difference:5},{moveId:2,difference:2},{moveId:3,difference:4,moves:[{moveId:1,difference:6}];
drives.forEach(o=>o.moves.sort((a,b)=>a.difference-b.difference));
drives.sort((a,b)=>a.moves[0].difference-b.moves[0].difference);
控制台日志(驱动器)
您可以使用嵌套的方法,通过对内部移动进行排序,然后通过对第一个元素进行排序来对外部移动进行排序
var drives=drives=[{id:1,moves:[{moveId:1,difference:1},{moveId:2,difference:2}]},{id:2,moves:[{moveId:1,difference:3,moves:[{moveId:1,difference:5},{moveId:2,difference:2},{moveId:3,difference:4},{id:4,moves:[{moveId:1,difference:6}];
console.log(
_(驾驶)
.map(o=>Object.assign({},o,{moves:u.sortBy(o.moves,'difference')}))
.sortBy(({moves:[{difference}]})=>difference)
.value()
);代码>
。作为控制台包装{最大高度:100%!重要;顶部:0;}
在我看来,您的情况有两种解决方案。
为了得到您需要的解决方案,您需要决定对驱动器进行排名的方法。不幸的是,您的方法可能会在将来导致意外的结果
您会发现,在移动过程中会出现重复的差值,在这种情况下,您需要确定在排序算法中哪个驱动器的权重更大
在下面,您可以找到一个rankMap对象,该对象在不同驱动器之间具有最大和最小的差异,以帮助您对阵列进行排序
希望这有帮助
let drives = [
{id: 1, moves:[
{moveId: 1, difference: 1},
{moveId: 2, difference: 2}]
},
{id: 2, moves:[
{moveId: 1, difference: -2}]
},
{id: 3, moves:[
{moveId: 1, difference: 5},
{moveId: 2, difference: 2},
{moveId: 3, difference: 4}]
}
];
// we build a rankMap by which we will later sort the array of objects
let rankMap = {};
drives = drives.map(drive => {
let
biggestDiff = null,
smallestDiff = null;
let moves = _.orderBy(drive.moves, move => {
if(biggestDiff < move.difference || biggestDiff === null) {
biggestDiff = move.difference;
}
if(smallestDiff > move.difference || smallestDiff === null) {
smallestDiff = move.difference;
}
return move.difference;
}, ['asc']);
rankMap[drive.id] = {
smallestDiff: smallestDiff,
biggestDiff: biggestDiff
};
return Object.assign({}, drive, {
moves: moves
});
});
let
sortedByBiggestDifference = _.orderBy(drives, drive => rankMap[drive.id].biggestDiff, ['asc']),
sortedBySmallestDifference = _.orderBy(drives, drive => rankMap[drive.id].smallestDiff, ['asc']);
console.log(drives);
console.log(sortedByBiggestDifference);
console.log(sortedBySmallestDifference);
let驱动器=[
{id:1,移动:[
{moveId:1,差分:1},
{moveId:2,差分:2}]
},
{id:2,移动:[
{moveId:1,差:-2}]
},
{id:3,移动:[
{moveId:1,差分:5},
{moveId:2,difference:2},
{moveId:3,差分:4}]
}
];
//我们构建了一个rankMap,稍后我们将根据它对对象数组进行排序
设rankMap={};
驱动器=驱动器。映射(驱动器=>{
让
biggestDiff=null,
smallestDiff=null;
let moves=u.orderBy(drive.moves,move=>{
if(biggestDiffmove.difference | | smallestDiff===null){
smallestDiff=移动差;
}
返回移动。差异;
},[asc']);
rankMap[drive.id]={
smallestDiff:smallestDiff,
biggestDiff:biggestDiff
};
返回对象。分配({},驱动器{
招式:招式
});
});
让
sortedByBiggestDifference=..orderBy(驱动器,驱动器=>rankMap[drive.id].biggestDiff,['asc']),
sortedBySmallestDifference=u.orderBy(drives,drive=>rankMap[drive.id].smallestDiff,['asc']);
控制台日志(驱动器);
console.log(sortedByBiggestDifference);
console.log(sortedBySmallestDifference);
Hmm..你指的是每个司机的差异之和吗?不是移动差异之和。首先,每个驱动器对象的移动数组应按其差异(或任何其他键)排序。之后,驱动器阵列应按移动的差异进行排序。-我编辑了我的文章,我希望它现在更清晰。@michaelT:请看一下我的第一部分的解决方案。至于第二部分,我提出了一个案例,请帮助回答,以便继续您的第二次排序解决方案仅基于第一项?你能看看我提出的案子吗?你认为OP想要什么?id 1首先出现,然后是id 2,因为id 1的移动最小差值为-3,id 2为-2(如果我使用升序)。当有两个驱动器对象具有相同的最小移动差异时,两个对象的顺序并不重要。请务必查看解决方案。这与@Hassan的答案基本相同,只是语法差异。您的解决方案也可以正常工作。非常感谢。但我有一个问题:如果我想使用一个函数来对驱动器数组进行排序,它使用了一个动态排序键,比如函数sortDirves(sortKey)——因为我在move的对象中有不止一个差分键。如何在代码中插入动态排序键?只是使用a.moves[0][sortKey]而不是a.moves[0]。差异?只是尝试了一下,效果如我所愿!太好了,谢谢!
let drives = [
{id: 1, moves:[
{moveId: 1, difference: 1},
{moveId: 2, difference: 2}]
},
{id: 2, moves:[
{moveId: 1, difference: -2}]
},
{id: 3, moves:[
{moveId: 1, difference: 5},
{moveId: 2, difference: 2},
{moveId: 3, difference: 4}]
}
];
// we build a rankMap by which we will later sort the array of objects
let rankMap = {};
drives = drives.map(drive => {
let
biggestDiff = null,
smallestDiff = null;
let moves = _.orderBy(drive.moves, move => {
if(biggestDiff < move.difference || biggestDiff === null) {
biggestDiff = move.difference;
}
if(smallestDiff > move.difference || smallestDiff === null) {
smallestDiff = move.difference;
}
return move.difference;
}, ['asc']);
rankMap[drive.id] = {
smallestDiff: smallestDiff,
biggestDiff: biggestDiff
};
return Object.assign({}, drive, {
moves: moves
});
});
let
sortedByBiggestDifference = _.orderBy(drives, drive => rankMap[drive.id].biggestDiff, ['asc']),
sortedBySmallestDifference = _.orderBy(drives, drive => rankMap[drive.id].smallestDiff, ['asc']);
console.log(drives);
console.log(sortedByBiggestDifference);
console.log(sortedBySmallestDifference);