我想用多个条件对数组进行排序

问题描述 投票:0回答:4

假设我有这个数组:

const services = [
    { id: 100, priority: 'Y', count: 300, payout: '30', id_region: 137 },
    { id: 101, priority: 'N', count: 200, payout: '40', id_region: 153 },
    { id: 102, priority: 'Y', count: 400, payout: '30', id_region: 137 },
    { id: 103, priority: 'Y', count: 500, payout: '50', id_region: 153 },
    { id: 104, priority: 'Y', count: 800, payout: '80', id_region: 222 }
];

这个全局变量:

var regionsFound = ['153'];

我要排序:

  • 首先是 id_region(如果它出现在regionsFound中)
  • 然后优先考虑“Y”
  • 然后是最高赔付
  • 然后是 id_region(如果没有出现在regionsFound中)
  • 然后数数

这是我的代码:

services.sort((a, b) => {
 if (regionsFound.indexOf(a.id_region.toString()) >= 0 && regionsFound.indexOf(b.id_region.toString()) >= 0){
    if (a.priority == 'Y' && b.priority == 'N'){
        return -1;
    } else if (a.priority == 'N' && b.priority == 'Y'){
        return 1;
    }
    return b.payout - a.payout;    
 } else if (regionsFound.indexOf(a.id_region.toString()) >= 0 && regionsFound.indexOf(b.id_region.toString()) < 0){
    return -1;
 } else {
    return b.count - a.count; 
 }
});

所以结果应该是:

const services = [
    { id: 103, priority: 'Y', count: 500, payout: '50', id_region: 153 },
    { id: 101, priority: 'N', count: 200, payout: '40', id_region: 153 },
    { id: 104, priority: 'Y', count: 800, payout: '80', id_region: 222 },
    { id: 102, priority: 'Y', count: 400, payout: '30', id_region: 137 },
    { id: 100, priority: 'Y', count: 300, payout: '30', id_region: 137 }
];

不知道错在哪里。

这是评论后的最终代码:

services.sort((a, b) => {
    if (regionsFound.indexOf(a.id_region.toString()) >= 0 && regionsFound.indexOf(b.id_region.toString()) < 0){
        return -1;
    } else if (regionsFound.indexOf(a.id_region.toString()) < 0 && regionsFound.indexOf(b.id_region.toString()) >= 0){
        return 1;
    } else if (regionsFound.indexOf(a.id_region.toString()) < 0 && regionsFound.indexOf(b.id_region.toString()) < 0){
        return b.count - a.count; 
    } else {
        if (a.priority == 'Y' && b.priority == 'N'){
            return -1;
        } else if (a.priority == 'N' && b.priority == 'Y'){
            return 1;
        }
        return parseFloat(b.payout) - parseFloat(a.payout);
    }
});
javascript arrays sorting
4个回答
2
投票

我认为如果你不嵌套 if 语句,你会省去很多麻烦。像这样的事情应该可以解决问题:

const services = [
    { id: 100, priority: 'Y', count: 300, payout: '30', id_region: 137 },
    { id: 101, priority: 'N', count: 200, payout: '40', id_region: 153 },
    { id: 102, priority: 'Y', count: 400, payout: '30', id_region: 137 },
    { id: 103, priority: 'Y', count: 500, payout: '50', id_region: 153 },
    { id: 104, priority: 'Y', count: 800, payout: '80', id_region: 222 }
];
var regionsFound = ['153'];

services.sort((a, b) => {
    // first the id_region if that appears in regionsFound
    const aInRegionsFound = regionsFound.includes(String(a.id_region));
    const bInRegionsFound = regionsFound.includes(String(b.id_region));

    if (aInRegionsFound !== bInRegionsFound) return aInRegionsFound ? -1 : 1;

    // then priority 'Y' first
    if (a.priority !== b.priority) return a.priority === 'Y' ? -1 : 1;

    // then highest payout
    if (a.payout !== b.payout) return Number(a.payout) > Number(b.payout) ? -1 : 1;

    // then the id_region if that doesn't appear in regionsFound
    if (a.id_region !== b.id_region) return a.id_region > b.id_region ? -1 : 1;

    // then count
    return b.count - a.count
});

0
投票

你差不多已经完成了,你只需要先将

payout
值转换为数字,然后才能正确排序。

我还更改了

indexof
include
以获得更清晰的代码

const services = [
    { id: 100, priority: 'Y', count: 300, payout: '30', id_region: 137 },
    { id: 101, priority: 'N', count: 200, payout: '40', id_region: 153 },
    { id: 102, priority: 'Y', count: 400, payout: '30', id_region: 137 },
    { id: 103, priority: 'Y', count: 500, payout: '50', id_region: 153 },
    { id: 104, priority: 'Y', count: 800, payout: '80', id_region: 222 }
];

var regionsFound = ['153'];

services.sort((a, b) => {
    const aRegionFound = regionsFound.includes(a.id_region.toString());
    const bRegionFound = regionsFound.includes(b.id_region.toString());

    if (aRegionFound === bRegionFound) {
        if (a.priority === 'Y' && b.priority === 'N') {
            return -1;
        } else if (a.priority === 'N' && b.priority === 'Y') {
            return 1;
        }
        return parseInt(b.payout) - parseInt(a.payout);
    } else if (aRegionFound && !bRegionFound) {
        return -1;
    } else if (!aRegionFound && bRegionFound) {
        return 1;
    } else {
        return b.count - a.count;
    }
});

console.log(services)


0
投票

您可以使用

||
链接减法运算,因为
-
运算符将其操作数转换为数字。

对于区域查找,我建议使用

Set

不清楚

id_region
是如何排序的,如果需要,只需交换
a
b
即可。

const services = [
    { id: 100, priority: 'Y', count: 300, payout: '30', id_region: 137 },
    { id: 101, priority: 'N', count: 200, payout: '40', id_region: 153 },
    { id: 102, priority: 'Y', count: 400, payout: '30', id_region: 137 },
    { id: 103, priority: 'Y', count: 500, payout: '50', id_region: 153 },
    { id: 104, priority: 'Y', count: 800, payout: '80', id_region: 222 }
];
var regionsFound = ['153'];

const regions = new Set(regionsFound.map(id => +id));

services.sort((a, b) => 
  regions.has(b.id_region) - regions.has(a.id_region) ||
  (b.priority === 'Y') - (a.priority === 'Y') ||
  b.payout - a.payout || 
  a.id_region - b.id_region ||
  b.count - a.count
)
      
services.forEach(s => console.log(JSON.stringify(s)));


0
投票

对多个条件使用排序功能,如下所示

const services = [
  { id: 100, priority: "Y", count: 300, payout: "30", id_region: 137 },
  { id: 101, priority: "N", count: 200, payout: "40", id_region: 153 },
  { id: 102, priority: "Y", count: 400, payout: "30", id_region: 137 },
  { id: 103, priority: "Y", count: 500, payout: "50", id_region: 153 },
  { id: 104, priority: "Y", count: 800, payout: "80", id_region: 222 },
];

const sortTypes = [
  { field: "id_region", found: ["153"] },
  { field: "priority", found: ["Y"] },
  { field: "payout", desc: true },
  { field: "count", asc: true },
];

const sort = (list, types) => {
  return list.sort((a, b) => {
    return types.reverse().reduce((init, type) => {
      const field = type.field;
      const x = a[field];
      const y = b[field];
      if (type.found && type.found.length) {
        const items = type.found;
        let xIdx = items.indexOf(x.toString());
        let yIdx = items.indexOf(y.toString());
        xIdx = xIdx == -1 ? items.length : xIdx;
        yIdx = yIdx == -1 ? items.length : yIdx;
        init = xIdx <= yIdx ? -1 : 1;
      } else if (type.asc) {
        init = x <= y ? -1 : 1;
      } else if (type.desc) {
        init = x >= y ? -1 : 1;
      }
      return init;
    }, 0);
  });
};
const sortList = sort(services, sortTypes);
console.log("sortList", sortList);

© www.soinside.com 2019 - 2024. All rights reserved.