我的数组如下,
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" }
]
如何实现?
答案 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>