我有一个包含以下对象的数据数组
[
{
"name":"Q1'2016",
"y":0
},
{
"name":"Q2'2016",
"y":0
},
{
"name":"Q3'2016",
"y":0
},
{
"name":"Q4'2015",
"y":0
}
]
我想根据季度对它们进行排序,因此Q4' 2015应该先行,然后是Q1&2016;等等。
如何实现这一目标?
答案 0 :(得分:1)
您可以使用sort
方法并根据谓词对其进行回调以对对象进行排序;在您的情况下,您要检查包含您的四分之一年信息的对象的名称属性。由于您可能拥有不同季度和年份的数据,因此您需要将季度映射到月份值,以便将它们转换为年/月日期并以这种方式进行比较。
var data = [{
"name": "Q1'2016",
"y": 0
}, {
"name": "Q2'2016",
"y": 0
}, {
"name": "Q3'2016",
"y": 0
}, {
"name": "Q4'2015",
"y": 0
}];
var quarterToMonthMap = {
"Q1": 0,
"Q2": 3,
"Q3": 6,
"Q4": 9
}
function sortByQuarterYear(lhs, rhs) {
var lhsQuarterYear = lhs.name.split("'");
var rhsQuarterYear = rhs.name.split("'");
var lhsDate = new Date(lhsQuarterYear[1], quarterToMonthMap[lhsQuarterYear[0]]);
var rhsDate = new Date(rhsQuarterYear[1], quarterToMonthMap[rhsQuarterYear[0]]);
return lhsDate.getTime() - rhsDate.getTime();
}
document.write(JSON.stringify(data.sort(sortByQuarterYear)));
答案 1 :(得分:1)
要按年份和季度排序,您可以使用以下ES6代码段(您可以使用ES5执行完全相同的操作,但我喜欢编写ES6)
input.map((obj, index) => obj.name.split("'").reverse().concat(index)).sort().map(arr => input[arr[2]]);
让我们稍微分解一下
input.map((obj, index) => obj.name.split("'").reverse().concat(index))
map()方法创建一个新数组,其结果是在此数组中的每个元素上调用提供的函数 <子> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map 子>
我们的“提供的函数”用'
字符拆分每个对象的“name”属性,反转生成的数组,并将当前索引添加到结果数组中。
这会产生一个如下所示的数组:
[
["2016", "Q1", 0],
["2016", "Q2", 1],
["2016", "Q3", 2],
["2015", "Q4", 3]
]
然后我们拨打.sort
,
sort()方法对数组中的元素进行排序并返回数组。排序不一定稳定。默认排序顺序是根据字符串Unicode代码点 <子> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort 子>
然后我们最终得到一个这样的数组:
[
["2015", "Q4", 3],
["2016", "Q1", 0],
["2016", "Q2", 1],
["2016", "Q3", 2]
]
所以我们现在有一个附录,注意我们扔在那里的索引没有按顺序排列。我们可以利用这种缺乏秩序来创造秩序。
我们所要做的就是再次调用map,这次返回与我们临时数组中存储的索引相关的原始对象。
.map(arr => input[arr[2]]);
当我们将它们放在一起并调用它时,我们最终得到一个这样的数组:
[
{
name: "Q4'2015",
y: 0
}, {
name: "Q1'2016",
y: 0
}, {
name: "Q2'2016",
y: 0
}, {
name: "Q3'2016",
y: 0
}
]
这是一个演示:
let input = [
{
"name":"Q1'2016",
"y":0
},
{
"name":"Q2'2016",
"y":0
},
{
"name":"Q3'2016",
"y":0
},
{
"name":"Q4'2015",
"y":0
}
];
input = input.map((obj, index) => obj.name.split("'").reverse().concat(index)).sort().map(arr => input[arr[2]]);
console.log(input);
在ES5中做同样的事情:
input.map(function(obj, index){
return obj.name.split("'").reverse().concat(index);
}).sort().map(function(arr){
return input[arr[2]];
});
答案 2 :(得分:0)
将.sort()
与比较器功能结合使用,您可以轻松地将每个值从"Q1'2016"
重新格式化为"2016Q1"
,从而允许进行简单的字母数字比较,因为"2016Q1" > "2015Q4"
。
function sortQuarters(arr) {
function reformat(v) {
return v.replace(/(Q\d)'(\d{4})/, "$2$1");
}
return arr.sort(function(a, b) {
return reformat(a.name).localeCompare(reformat(b.name));
});
}
console.log(sortQuarters([
{ "name":"Q1'2016", "y":0 },
{ "name":"Q3'2016", "y":0 },
{ "name":"Q2'2016", "y":0 },
{ "name":"Q4'2015", "y":0 }
]));
(请注意,我所说的重新格式化仅在排序时使用的临时变量中,它不会更改数组中的值。另请注意,我显示的函数会修改传递给的数组的顺序。它并返回相同的数组,它不会创建一个新数组。)