簡體   English   中英

根據多個屬性對對象數組進行排序

[英]Sort array of objects based on multiple properties

我正在嘗試根據對象內部的任意屬性對對象數組進行排序。 我寫了下面的代碼,效果很好。

var customSort = function(data, sortBy, order) {
  if (!(data && sortBy)) {
    throw new Error('Specify the data source and atleast one property to sort it by');
  }
  if (!Array.isArray(data)) {
    throw new Error('Specify the data source as an array');
  }
  order = order || 'asc';

  function performSort(order, sortBy) {
    return data.sort(function(a, b) {
      var A = parse(a, sortBy);
      var B = parse(b, sortBy);
      if (A < B) {
        return order === 'asc' ? -1 : 1;
      } else if (A > B) {
        return order === 'asc' ? 1 : -1;
      } else {
        return 0;
      }
    });
  }

  function parse(data, sortBy) {
    var sortParams = sortBy.split('.');
    var latestValue = data;
    for (var i = 0; i < sortParams.length; i++) {
      latestValue = latestValue[sortParams[i]];
    }
    if (!latestValue) {
      throw new Error('Check the \'sortBy\' parameter. Unreachable parameter in \'sortBy\'');
    }
    if (typeof latestValue === 'string') {
      return latestValue.toLowerCase();
    } else {
      return latestValue;
    }
  }

  return performSort(order, sortBy);
};

var lonelyData = [{
  a: {
    b: 2
  }
}, {
  a: {
    b: 1
  }
}, {
  a: {
    b: 9
  }
}, {
  a: {
    b: 7
  }
}, {
  a: {
    b: 4
  }
}, {
  a: {
    b: 2
  }
}, {
  a: {
    b: 1
  }
}];

console.log(customSort(lonelyData, 'a.b'));

小提琴在這里: JSFiddle



現在,我嘗試使用遞歸以以下方式對多個屬性進行排序:首先,按第一個屬性排序,然后在同一屬性內,按第二個屬性排序,依此類推。 為了簡單起見,我假設所有屬性的順序相同,即全部遞增或全部遞減。
我寫了這段代碼:

var customSort = function(data, sortBy, order) {
  if (!(data && sortBy)) {
    throw new Error('Specify the data source and atleast one property to sort it by');
  }
  if (!Array.isArray(data)) {
    throw new Error('Specify the data source as an array');
  }
  if (!Array.isArray(sortBy)) {
    sortBy = [sortBy];
  }
  order = order || 'asc';

  function performSort(order, sortBy) {
    return data.sort(function(a, b) {
      function nestedSort() {
        var highestOrder = sortBy[0];
        var A = parse(a, highestOrder);
        var B = parse(b, highestOrder);
        if (A < B) {
          return order === 'asc' ? -1 : 1;
        } else if (A > B) {
          return order === 'asc' ? 1 : -1;
        } else {
          sortBy.shift();
          nestedSort();
        }
      }
      return nestedSort();
    });
  }

  function parse(data, sortBy) {
    var sortParams = sortBy.split('.');
    var latestValue = data;
    for (var i = 0; i < sortParams.length; i++) {
      latestValue = latestValue[sortParams[i]];
    }
    if (!latestValue) {
      throw new Error('Check the \'sortBy\' parameter. Unreachable property passed in \'sortBy\'');
    }
    if (typeof latestValue === 'string') {
      return latestValue.toLowerCase();
    } else {
      return latestValue;
    }
  }

  return performSort(order, sortBy);
};

var lonelyData = [{
  a: {
    b: 2,
    c: 'Z'
  }
}, {
  a: {
    b: 2,
    c: 'A'
  }
}, {
  a: {
    b: 9,
    c: 'Q'
  }
}, {
  a: {
    b: 7,
    c: 'L'
  }
}, {
  a: {
    b: 7,
    c: 'E'
  }
}, {
  a: {
    b: 1,
    c: 'A'
  }
}, {
  a: {
    b: 1,
    c: 'B'
  }
}];

console.log(customSort(lonelyData, ['a.b', 'a.c']));

小提琴在這里: JSFiddle


不幸的是,我無法使其工作。 我在這里想念什么?

  sortBy.shift(); nestedSort(); 

是你的問題。 shift會改變數組,並永久刪除第一項。 下次調用比較函數將ab進行比較時,它將被忽略,並且很快數組將為空並且您的比較完全中斷。

而是使用一個簡單的循環:

return data.sort(function(a, b) {
  for (var i=0; i<sortBy.length; i++)
    var currentOrder = sortBy[i];
    var A = parse(a, currentOrder);
    var B = parse(b, currentOrder);
    if (A < B) {
      return order === 'asc' ? -1 : 1;
    } else if (A > B) {
      return order === 'asc' ? 1 : -1;
    }
  }
  return 0;
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM