【问题标题】:Sort an array of object by a property (with custom order, not alphabetically)按属性对对象数组进行排序(使用自定义顺序,不按字母顺序)
【发布时间】:2018-04-19 21:41:03
【问题描述】:

我想就这个小问题寻求您的帮助。

我想根据 code 值对这个数组进行排序但不是按字母顺序。我用粗体标出了这个,但最终还是被标记了,人们甚至不关心阅读这个问题

例如,我想要所有 green 对象,然后是所有 blue 对象,然后是所有 red 对象。最好的方法是什么?

[
    { code: "RED", value: 0},
    { code: "BLUE", value: 0},
    { code: "RED", value: 0},
    { code: "GREEN", value: 0},
    { code: "BLUE", value: 0},
    { code: "RED", value: 0},
    { code: "GREEN", value: 0},
    { code: "BLUE", value: 0}
]

是否可以使用 sort 功能做到这一点?在那种情况下会是什么条件?

【问题讨论】:

  • @JasperSeinhorst 我刚刚遍历了数组,我想看看是否有更快的方法。
  • @lilezek 请在标记前阅读问题,我不希望它按字母顺序排列
  • @LucaDeNardi 从字面上看,您只需要编写自己的排序函数。
  • @lilezek 根本不是真的,因为有人提供了一种更快的方法来做到这一点。
  • @LucaDeNardi 这里大家提供了排序功能。

标签: javascript arrays sorting


【解决方案1】:

你可以为想要的订单拿一个对象。

var array = [{ code: "RED", value: 0 }, { code: "BLUE", value: 0 }, { code: "RED", value: 0 }, { code: "GREEN", value: 0 }, { code: "BLUE", value: 0 }, { code: "RED", value: 0 }, { code: "GREEN", value: 0 }, { code: "BLUE", value: 0 }],
    order = { GREEN: 1, BLUE: 2, RED: 3 };
    
array.sort(function (a, b) {
    return order[a.code] - order[b.code];
});

console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }

对于未知的颜色/值,您可以使用默认值

  • 0,用于排序到顶部或
  • Infinity 或有人建议,因为能够计算 Number.MAX_VALUE 以进行排序,
  • 或用于在其他组之间排序的任何其他值。

最后你可以用另一个排序部分对特殊处理的项目进行排序,用logical OR ||链接。

var array = [{ code: "YELLOW", value: 0 }, { code: "BLACK", value: 0 }, { code: "RED", value: 0 }, { code: "BLUE", value: 0 }, { code: "RED", value: 0 }, { code: "GREEN", value: 0 }, { code: "BLUE", value: 0 }, { code: "RED", value: 0 }, { code: "GREEN", value: 0 }, { code: "BLUE", value: 0 }],
    order = { GREEN: 1, BLUE: 2, RED: 3, default: Infinity };
    
array.sort(function (a, b) {
    return (order[a.code] || order.default) - (order[b.code] || order.default) || a.code.localeCompare(b.code);
});

console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 嗯,这很有趣!我没有考虑使用对象来跟踪订单:)
【解决方案2】:

先设置自定义优先级

var codePriority = [ "GREEN", "BLUE", "RED" ];

现在在排序中使用相同的

arr.sort( function(a,b){ 
   if ( a.code == b.code ) return a.value - b.value;
   return codePriority.indexOf( a.code ) - codePriority.indexOf( b.code ) ; notice this line
})

演示

var arr = [
    { code: "RED", value: 0},
    { code: "BLUE", value: 0},
    { code: "RED", value: 0},
    { code: "GREEN", value: 0},
    { code: "BLUE", value: 0},
    { code: "RED", value: 0},
    { code: "GREEN", value: 0},
    { code: "BLUE", value: 0}
];
var codePriority = [ "GREEN", "BLUE", "RED" ];
arr.sort( function(a,b){ 
   if ( a.code == b.code ) return a.value - b.value;
   return codePriority.indexOf( a.code ) - codePriority.indexOf( b.code )
});
console.log( arr );

【讨论】:

  • 您可以删除if 检查。试试return codePriority.indexOf( a.code ) - codePriority.indexOf( b.code ) || a.value - b.value
  • @Rajesh 哦,没想到 :)... 我暂时保持原样,它更具可读性。
【解决方案3】:

您可以实现一个模式数组并根据该模式数组中元素的索引进行排序。

const a = ['GREEN', 'BLUE', 'RED'];

const o = [{code:"RED",value:0},{code:"BLUE",value:0},{code:"RED",value:0},{code:"GREEN",value:0},{code:"BLUE",value:0},{code:"RED",value:0},{code:"GREEN",value:0},{code:"BLUE",value:0}];

const r = o.slice().sort(({ code: q }, { code: w }) => a.indexOf(q) - a.indexOf(w));

console.log(r);

【讨论】:

    【解决方案4】:

    这是一个按特定颜色排序的函数。

    const colors = [{
        name: "T-shirt",
        color: "red",
        price: 20
      },
      {
        name: "Shoes",
        color: "yellow",
        price: 20
      },
      {
        name: "Pants",
        color: "red",
        price: 20
      },
      {
        name: "Cap",
        color: "yellow",
        price: 20
      },
      {
        name: "Skirt",
        color: "red",
        price: 15
      },
    ]
    
    let sortByColor = color => colors.sort((a, b) => a.color === color ? -1 : 1)
    
    console.log(sortByColor('red'))

    【讨论】:

      【解决方案5】:

      可以使用排序函数即Array.prototype.sort()访问https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

      首先,您必须决定是按升序还是降序排序。 要按升序排序,您可以执行以下操作:

      arr.sort((a, b) => {
          return a.color < b.color ? -1 : a.color > b.color ? 1 : 0;
        });
      

      按降序排列:

      arr.sort((a, b) => {
          return a.color > b.color ? -1 : a.color < b.color ? 1 : 0;
        });
      

      现在假设您希望首先对某种颜色进行排序和显示。你可以有这样的功能:

      const sortByKeyAsc = (arr,color) =>
        arr.sort((a, b) => {
          if(a.color < b.color || (a.color === color && b.color !== color)){
            return -1;
          }
          if(a.color > b.color || (a.color !== color && b.color === color)){
            return 1
          }
          return 0;
        });
      

      你可以这样使用它:

      const array1 = sortByKeyAsc(arr,'pink');
      

      【讨论】:

        【解决方案6】:

        我正在处理一个必须匹配字符串状态并专门按各种状态排序的情况。 .findIndex.includes 最终成为最好的方法。

        statusPriority 设置预期的顺序。一旦找到索引,就可以将它们进行比较并返回给 .sort

        let records = [
          {status: 'Record is ready to submit.', active: true, name: 'A'},
          {status: 'Record has been sent.', active: true, name: 'B'},
          {status: 'Activation is required.', active: true, name: 'C'},
          {status: 'Record submission failed.', active: true, name: 'D'},
          {status: 'Creation is pending.', active: true, name: 'E'},
        ]
        
        console.log(records.map(r => r.status))
        
        let statusPriority = ['creation', 'activation', 'sent', 'ready', 'failed'];
        records.sort((a, b) => {
          let aIndex = statusPriority.findIndex(status => a.status.toLowerCase().includes(status));
          let bIndex = statusPriority.findIndex(status => b.status.toLowerCase().includes(status));
          return aIndex - bIndex;
        })
        
        console.log(records.map(r => r.status))

        【讨论】:

          【解决方案7】:

          您可以使用此功能按字母顺序对颜色进行排序

            var sortedArr = arr.sort((first, second)=>{
                      
                  return first.color < second.color ? -1 : 1
              })
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-06-15
            • 2012-02-12
            • 1970-01-01
            • 1970-01-01
            • 2014-12-30
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多