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);