按年和月对数组排序

时间:2018-08-18 09:25:15

标签: javascript arrays angular sorting lodash

我的数组如下,

let  yearAndMonth  =  [
    { "year": 2013, "month": "FEBRUARY" },
    { "year": 2015, "month": "MARCH" },
    { "year": 2013, "month": "JANUARY" },
    { "year": 2015, "month": "FEBRUARY" }
]

我想先按对数组进行排序,然后再按年份对进行排序,

我想要这样的输出

yearAndMonth  =  [
    { "year": 2013, "month": "JANUARY " },
    { "year": 2013, "month": "FEBRUARY" },
    { "year": 2015, "month": "FEBRUARY" },
    { "year": 2015, "month": "MARCH" }
]

如何实现?

7 个答案:

答案 0 :(得分:3)

您可以使用一个对象来表示月份名称及其数值。

通过获取年份和月份的增量来链接订单。

var array =  [{ year: 2013, month: "FEBRUARY" }, { year: 2015, month: "MARCH" }, { year: 2013, month: "JANUARY" }, { year: 2015, month: "FEBRUARY" }];

array.sort(function (a, b) {
    var MONTH = { JANUARY: 0, FEBRUARY: 1, MARCH: 2, APRIL: 3, MAY: 4, JUNE: 5, JULY: 6, AUGUST: 7, SEPTEMBER: 8, OCTOBER: 9, NOVEMBER: 10, DECEMBER: 11 };
    return a.year - b.year || MONTH[a.month] - MONTH[b.month];
});

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

答案 1 :(得分:1)

您可以制作将月份映射到月份号的映射,然后将Arrays.sort()与您自己的自定义比较器一起使用:

let months = { 'JANUARY' : 1, 'FEBRUARY' : 2, 'MARCH' : 3, 'APRIL' : 4, 'MAY' : 5, 'JUNE' : 6, 'JULY' : 7, 'AUGUST' : 8, 'SEPTEMBER' : 9, 'OCTOBER' : 10, 'NOVEMBER' : 11, 'DECEMBER' : 12 };
let  yearAndMonth  =  [ { "year": 2013, "month": "FEBRUARY" }, { "year": 2015, "month": "MARCH" }, { "year": 2013, "month": "JANUARY" }, { "year": 2015, "month": "FEBRUARY" } ];

yearAndMonth.sort((a,b)=> a.year - b.year || months[a.month.toUpperCase()] - months[b.month.toUpperCase()]);

console.log(yearAndMonth);

答案 2 :(得分:1)

您可以创建一个包含月份名称的数组,并进行如下排序:

let data = [
  { "year": 2013, "month": "FEBRUARY" }, { "year": 2015, "month": "MARCH" },
  { "year": 2013, "month": "JANUARY" }, { "year": 2015, "month": "FEBRUARY" }
];

let months = ["JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE",
              "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER"];

data.sort(
 (a, b) => (a.year - b.year) || (months.indexOf(a.month) - months.indexOf(b.month))
);


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

答案 3 :(得分:1)

既然您可以使用lodash,可以通过简单的sortBy

来实现。

_.sortBy(yearAndMonth, a => new Date(1+ a.month + a.year))

它将为每个月和每年(日期为1)构造一个new Date,并且应该按照您想要的方式工作。

let  yearAndMonth  =  [
    { "year": 2013, "month": "FEBRUARY" },
    { "year": 2015, "month": "MARCH" },
    { "year": 2013, "month": "JANUARY" },
    { "year": 2015, "month": "FEBRUARY" }
]

let res = _.sortBy(yearAndMonth, a => new Date(1 + a.month + a.year));
console.log('Sorted Result: ', res);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

注意:您不需要所有月份的 array / object / map 即可执行><

答案 4 :(得分:0)

您还可以使用lodash库按多列对数据进行排序。

我已经在 Stackblitz 上创建了一个演示。希望这对您/其他人有所帮助/指南。

lodash- Documentation

  

Component.html

<table width="100%">
  <tr>
    <td>Year</td>
    <td>Month</td>
  </tr>
  <tr *ngFor="let datas of sortedData">
    <td>{{datas.year}}</td>
    <td>{{datas.month}}</td>
  </tr>
</table>
  

Component.ts

 sortedData: any[];
  data = [
    { "year": 2013, "month": "FEBRUARY" },
    { "year": 2015, "month": "MARCH" },
    { "year": 2013, "month": "JANUARY" },
    { "year": 2013, "month": "MARCH" },
    { "year": 2013, "month": "APRIL" },
    { "year": 2015, "month": "FEBRUARY" }
  ];

monthArray: any = ["JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE",
        "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER"];

  ngOnInit() {
    this.sortedData = _.orderBy(data, [(datas) => datas.year, (user) => (this.monthArray.indexOf(user.month))], ["asc", "asc"]);
    console.log(this.sortedData);
  }

答案 5 :(得分:0)

在数组中声明月份名称,以获取彼此比较时月份字符串的相对值。

第一次比较将在年份上,如果两个年份的值都相同,则根据创建的months数组进行月份比较。

let months = ["JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE",
          "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER"];



yearAndMonth.sort((a,b) =>{
    if(a.year > b.year) return 1;
    else if(a.year <  b.year) return -1;
    else {
        if(months.indexOf(a.month.toUpperCase()) > 
           months.indexOf(b.month.toUpperCase()))
               return 1;
        else if(months.indexOf(a.month.toUpperCase()) < 
         months.indexOf(b.month.toUpperCase())) 
               return -1
        else return 0;
  }
});

答案 6 :(得分:0)

另请参阅:JsFiddle

允许我提供一个普通的ES版本(对1个或多个键值进行对象排序,对序列进行依赖(对1进行排序,在1内对2排序,在1和2内对3进行排序,依此类推),即不可变,即保持原始数组不变):

const log = (...str) => 
  document.querySelector("pre").textContent += `${str.join("\n")}\n`;
const data = getData();
const xSort = XSort();
const months = [ "JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE",
    "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER" ];

log( JSON.stringify(
    xSort
    .create(data)
    .orderBy( {key: "year"}, { key: v => months.indexOf(v.month) } ),
    null,
    " ")
  );

function XSort() {
  const multiSorter = sortKeys => {
    if (!sortKeys || sortKeys[0].constructor !== Object) {
      throw new TypeError("Provide at least one {key: [keyname]} to sort on");
    }
    return function (val0, val1) {
      for (let sortKey of sortKeys) {
        const v0 = sortKey.key instanceof Function ? sortKey.key(val0) : val0[sortKey.key];
        const v1 = sortKey.key instanceof Function ? sortKey.key(val1) : val1[sortKey.key];
        const isString = v0.constructor === String || v1.constructor === String;
        const compare = sortKey.descending ?
          isString ? v1.toLowerCase().localeCompare(v0.toLowerCase()) : v1 - v0 :
          isString ? v0.toLowerCase().localeCompare(v1.toLowerCase()) : v0 - v1;
        if (compare !== 0) {
          return compare;
        }
      }
    };
  }
  const Sorter = function (array) {
    this.array = array;
  };

  Sorter.prototype = {
    orderBy: function(...sortOns) {
      return this.array.slice().sort(multiSorter(sortOns));
    },
  };

  return {
    create: array => new Sorter(array)
  };
}

function getData() {
  return [{
      "year": 2013,
      "month": "FEBRUARY",
    },
    {
      "year": 2015,
      "month": "MARCH",
    },
    {
      "year": 2015,
      "month": "SEPTEMBER",
    },
    {
      "year": 2013,
      "month": "JANUARY",
    },
    {
      "year": 2013,
      "month": "MARCH",
    },
    {
      "year": 2013,
      "month": "APRIL",
    },
    {
      "year": 2015,
      "month": "FEBRUARY",
    }
  ];
}
<pre></pre>