这篇文章主要介绍了如何按照一个或多个属性给一个对象数组排序。

需求

后台返回的数据需要按照一定的顺序展示,可以根据其中一个属性或多个属性。

解决办法

  • 单属性排序

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    // 创建动态排序函数,根据传递的值对对象进行排序:
    function dynamicSort(property) {
    var sortOrder = 1;
    if(property[0] === "-") {
    sortOrder = -1;
    property = property.substr(1)
    }
    return function (a,b) {
    // 下面一行代码对字符串和数字均有效
    // 你可以根据自己的需求定制它
    var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0
    return result * sortOrder
    }
    }

    // 待处理数据
    var data = [
    {name: 'tom4', mdate: '202012'},
    {name:'tom2', mdate:'202001'},
    {name: 'tom1', mdate: '202008'},
    {name: 'tom3', mdate: '202005'}
    ]

    // 使用:按照属性 mdate 给data排序
    let sortedArr = data.sort(dynamicSort("mdate"))
  • 多属性排序

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    function dynamicSortMultiple() {
    /*
    * 保存arguments对象,因为它将被覆盖
    * 注意arguments对象是一个类似数组的对象
    * 由要排序的属性的名称组成
    */
    var props = arguments
    return function (obj1, obj2) {
    var i = 0, result = 0, numberOfProperties = props.length
    // 从0开始获取不同的结果,因为有多个属性需要比较
    while(result === 0 && i < numberOfProperties) {
    result = dynamicSort(props[i])(obj1, obj2)
    i++
    }
    return result
    }
    }

    // 使用:按照属性 name 和 mdate 给data排序
    let sortedArr = People.sort(dynamicSortMultiple("name", "mdate"));
  • 也可以使用ES6,它允许扩展原生对象

    1
    2
    3
    4
    5
    6
    7
    8
    class MyArray extends Array {
    sortBy(...args) {
    return this.sort(dynamicSortMultiple.apply(null, args))
    }
    }

    // 使用:按照属性 mdate 给data排序
    let sortedArr = MyArray.from(data).sortBy("mdate")

备注

  • 注意多属性排序中有一行代码 dynamicSort(props[i])(obj1, obj2),因为dynamicSort函数返回一个函数,要执行这个函数所以使用了两个括号。
  • f() 执行f函数,返回子函数。
  • f()() 执行子函数,返回孙函数。
  • 括号越多越往里面执行