我有以下结构:
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}]
}
]
现在我想根据移动的差异对驱动器数组进行排序。结果应该是这样的(取决于排序顺序)。
let drives = [
{id: 2, moves:[
{moveId: 1, difference: -2}]
},
{id: 1, moves:[
{moveId: 1, difference: 1},
{moveId: 2, difference: 2}]
},
{id: 3, moves:[
{moveId: 2, difference: 2},
{moveId: 3, difference: 4},
{moveId: 1, difference: 5}]
},
{id: 4, moves:[
{moveId: 1, difference: 6}]
}
]
我尝试使用此代码
使用lodash执行此操作_.orderBy(drives, 'moves.difference', 'asc');
但这似乎什么都不做。 有谁知道如何处理这个?
答案 0 :(得分: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}]
}
]
drives.forEach(x=> {
x.moves.sort(function (a, b) {
return a.difference - b.difference;
});
});
drives.sort(function (a, b) {
return a.moves[0].difference - b.moves[0].difference;
});
console.log(drives);

关于第二部分,我不确定你在id 2和id 1之间交换的条件是什么。
let drives = [
{id: 1, moves:[
{moveId: 1, difference: 1},
{moveId: 2, difference: 2}]
},
{id: 2, moves:[
{moveId: 1, difference: -2},
{moveId: 2, difference: 4}]
}]
如果对于上述情况,id:2
会先出现还是保持相同的序列?
答案 1 :(得分:0)
你可以排序两次。首先,对moves
数组进行排序。对所有moves
数组进行排序后。然后根据第一个索引处的difference
值进行排序。
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}] } ];
drives.forEach(o => o.moves.sort((a,b) => a.difference - b.difference));
drives.sort((a,b) => a.moves[0].difference - b.moves[0].difference);
console.log(drives);
答案 2 :(得分:0)
您可以使用嵌套方法对内部moves
进行排序,然后通过将第一个元素排序来进行外部移动。
var drives = 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 }] }];
console.log(
_(drives)
.map(o => Object.assign({}, o, { moves: _.sortBy(o.moves, 'difference') }))
.sortBy(({ moves: [{ difference }] }) => difference)
.value()
);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
答案 3 :(得分: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);