【问题标题】:Sort an object by each value in a sub object按子对象中的每个值对对象进行排序
【发布时间】:2018-06-22 01:16:36
【问题描述】:

我正在尝试对用于显示赛车联盟排名的对象进行排序。我需要能够对车手进行排序,而不是积分,而是过去的完成位置。如果车手最终获得相同数量的积分,那么之前的位置将从第一名开始,一直到最后一名,这取决于联盟中有多少车手。包含所有驱动程序的对象如下所示:

var standings = [{
    driver: "Bob",
    points: 45,
    positions: {
        0: 1,
        1: 0,
        2: 1,
        3: 2,
        4: 0
    }
}, {
    driver: "Mandy",
    points: 17,
    positions: {
        0: 0,
        1: 2,
        2: 4,
        3: 0,
        4: 1
    }
}, {
    driver: "Robert",
    points: 24,
    positions: {
        0: 0,
        1: 1,
        2: 5,
        3: 3,
        4: 0
    }
}];

位置对象是他们在特定位置完成的次数,键表示位置,因此键 0 = 1st Place,key 1 = 2nd Place。

positions 对象中键值的数量会随着联赛中车手的数量而变化。

我一直在尝试做的是弄清楚如何使用下划线 _.sortby 首先按最低位置对其进行排序,然后一直到第 1 位,然后最后按点位,但我似乎做不到找到一种方法来做到这一点 - 运行一个循环,对位置对象中的每个项目运行对象上的 sortby 函数似乎不起作用 - 它似乎只是重置。

我最初的尝试似乎不起作用:

var driverCount = 3;
for (i = 0; i < driverCount; i++) {
    standings = _.sortBy(standings, 'positions['+i+']').reverse();
}
standings = _.sortBy(standings, 'points').reverse();

有什么想法吗?

【问题讨论】:

  • 您拥有的 standings 对象不是有效的 JavaScript 语法
  • 我不确定我是否理解您的任务,但我可以从您的代码中看到,您正在覆盖 standings 值,并且您只有最后一个结果,请尝试改用standings[i] =
  • @Cerbrus 哎呀,刚刚更新得更像它应该的样子。虽然我在浏览器中没有看到任何关于位置对象设置方式的错误(如果我删除 for 循环,它似乎正在排序)我注意到 javascript 语法检查显示它不正确。
  • @Sheki 我正在尝试按多个值对我的对象进行排序。我想按“位置”对象中的每个键对其进行排序,最后按点数进行排序。 “如果车手积分相同,则根据结果倒数决定位置。比较胜利,获胜最多的车手排在前面。如果胜利相同,则查看第二名,依此类推。”我注意到你可以链接 _.sortby 但我不知道我是否可以使用 for 循环来做到这一点,因为不同的联赛会有不同数量的驱动程序,所以我不知道如何将字段传递给 sortby。跨度>
  • 我会将positions 对象更改为[{key:1,value:0},{key:2,value:2}] 等等,所以你可以这样说而不是_.sortBy(positions,'value')'

标签: javascript jquery sorting underscore.js


【解决方案1】:

将您的对象更改为:

    var standings = [{
        driver: "Bob",
        points: 45,
        positions: [
            {key:0, valeu:1},
            {key:1, valeu:0},
            {key:2, valeu:1},
            {key:3, valeu:2},
            {key:4, valeu:0}
        ]
    }, {
        driver: "Mandy",
        points: 17,
        positions: [
            {key:0, valeu:0},
            {key:1, valeu:2},
            {key:2, valeu:4},
            {key:3, valeu:0},
            {key:4, valeu:1}
        ]
    }, {
        driver: "Robert",
        points: 24,
        positions:[
             {key:0, valeu:0},
             {key:1, valeu:1},
             {key:2, valeu:5},
             {key:3, valeu:3},
             {key:4, valeu:0}
       ]
    }];

比使用排序功能对位置和排名进行排序:

for (i = 0; i < standings.length; i++) { 
    standings[i].positions = standings[i].positions.sort(()=>{ 
    if (a.value == b.value)
        return 0;
    if (a.value > b.value)
        return -1;
    else
        return 1;
   })
}

比对数组的其余部分进行排序:

standings.sort((a,b)=>{
    if (a.points == b.points)
        return 0;
    if (a.points > b.points)
        return -1;
    else
        return 1;
});

没有测试代码,但你理解的想法

【讨论】:

  • 这似乎并没有实现我所追求的 - 它只是对每个车手位置数组进行排序,然后按积分对积分榜进行排序,而不是按每个车手之前的位置排序积分榜,然后按积分排序.
  • 这就是为什么我说,我不确定我是否理解你的任务,“司机以前的职位”是什么?
【解决方案2】:

你有一个复合排序函数。

我会使用类似的东西:

_sortBy(standings, (o) => o.points+Math.min(... _.pluck(o.positions, 'value')))); // wtach out your key is missspelled valeu

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-08
    • 1970-01-01
    相关资源
    最近更新 更多