按两个关键字对一个对象数组进行排序,其中一个关键字有权重

4

考虑以下对象数组:

var arr = [
  { brand : 'BMW' , year : '2014' },
  { brand : 'Audi' , year : '2018' },
  { brand : 'Benz' , year : '2020' },
  { brand : 'BMW' , year : '2011' },
  { brand : 'Audi' , year : '2015' },
  { brand : 'BMW' , year : '2010' },
  { brand : 'BMW' , year : '2018' }
]

我试图按照品牌(不是按字母排序,而是按照特定权重...因此BMW拥有最高的权重=>奥迪=>奔驰)首先对这个数组进行排序,其次是按年份排序...所以我得到类似于这样的结果:

var arr = [
    { brand : 'BMW' , year : '2014' },
    { brand : 'BMW' , year : '2011' },
    { brand : 'BMW' , year : '2010' },
    { brand : 'Audi' , year : '2018' },
    { brand : 'Audi' , year : '2018' },
    { brand : 'Audi' , year : '2015' },
    { brand : 'Benz' , year : '2020' }
 ]

这是我迄今为止尝试过的,但似乎我并不真正理解 sort() 函数的用法:

function sortByBrand (a,b) {
    if(a.brand == 'BMW' && b.brand !=='BMW') {
        return 2
    }else if (a.brand == 'Audi' &&  b.brand !=='Audi') {
        return 1
    } else if (a.brand == 'Benz' &&  b.brand !=='Benz') {
        return 0
    }
}

function sortByYear (a,b) {
    return parseInt(b.year) - parseInt(a.year)
}

arr.sort(sortByBrand)
arr.sort(sortByYear)

我知道这会改变第一个排序,但我真的不知道如何将两个排序合并在一起。

看起来 { brand : 'BMW' , year : '2018' } 对象被丢掉了,这是有意为之吗?还是应该在预期输出数组的顶部? - CertainPerformance
2
你编辑了你的问题,但仍然没有明确排序品牌的标准。 - Gerardo Furtado
@GerardoFurtado 标准是字符串名称,因此请考虑以下顺序:BMW => 订单1 / Audi => 订单2 / Benz => 订单3。 - user121548789
2
在你的问题中,那个顺序在哪里指定?它只是数组中品牌值的顺序吗?如果是,请明确说明这一点。在问题中,而不是在评论中。 - Gerardo Furtado
1个回答

2
你可以使用localeCompare来检查一个字符串是否在另一个字符串之前或之后,它将返回1、0或-1。通过比较每个对象的.brand属性和localeCompare,如果结果为0,则按年份差异进行比较:
最初的回答

var arr = [
  { brand : 'A' , year : '2014' },
  { brand : 'B' , year : '2018' },
  { brand : 'C' , year : '2020' },
  { brand : 'A' , year : '2011' },
  { brand : 'B' , year : '2015' },
  { brand : 'A' , year : '2010' },
  { brand : 'B' , year : '2018' }
]

arr.sort((a, b) => (
  a.brand.localeCompare(b.brand)
  || b.year - a.year
));

console.log(arr);

请记住,.sort回调只关心返回值是负数、0还是正数。返回2与返回1相同(为了使排序算法一致,如果将ab进行比较返回正值,则将ba进行比较应返回负值)。
如果localeCompare不够复杂,请编写一个函数,该函数接受一个对象并返回品牌的适当权重:

var arr = [
  { brand : 'BMW' , year : '2014' },
  { brand : 'Audi' , year : '2018' },
  { brand : 'Benz' , year : '2020' },
  { brand : 'BMW' , year : '2011' },
  { brand : 'Audi' , year : '2015' },
  { brand : 'BMW' , year : '2010' },
  { brand : 'BMW' , year : '2018' }
];

const weights = {
  BMW: 2,
  Audi: 1,
  Benz: 0
};
const getWeight = ({ brand }) => weights[brand];

arr.sort((a, b) => (
  getWeight(b) - getWeight(a)
  || b.year - a.year
));

console.log(arr);


嗨,谢谢,听起来很不错。但我认为localCompare按字母顺序对字符串进行排序,而我正在尝试根据某些标准对品牌进行排序。例如,如果(a.brand =='A',那么我希望该品牌位于我的数组顶部。 - user121548789
3
创建一个包含所有品牌映射到它们相应权重的对象或映射表,然后在比较器内对其进行索引以进行比较。例如:weights = { foo: 2, bar: 1 }(a, b) => weights[a] - weights[b] || b.year - a.year - ggorlen
@user121548789,您能解释一下您想要的具体标准是什么吗? - CertainPerformance

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接