我有一个字符串数组,其中包含一个可选的双字母字符串,表示春天或秋天,后面跟着一个四位数的年份,即作为以下示例之一:
var example_data = ["HT2014", "VT2013", "2017"];
我想对这个数组进行排序,以便它主要按年份排序(即四位数字,作为数字),然后(如果年份相等),它被排序,以便VT是第一个,HT是中间和没有指定弹簧或秋天的条目是最后一个。
如果我已正确理解JavaScript sort()
函数,我应该能够实现一个sortFunction
,告诉我两个对象中哪一个应该是第一个,然后只调用{{ 1}}。
我也开始研究这样的data.sort(sortFunction)
,并提出以下建议:
sortFunction
正如评论所表明的那样,我不知道如何处理function specialSort(a,b) {
var as = a.split("T");
var bs = b.split("T");
if (as[1] != bs[1]) {
return as[1] - bs[1];
} else {
// The year is equal.
// How do I sort on term?
}
}
,"HT"
和"VT"
的排序(除了可能是一系列荒谬的嵌套{{1} }}š...)。 (另外,我知道上面的代码对于示例数据中的第三项会失败,因为""
只有1个元素。我会处理那个......)
这是一个好方法吗?如果是 - 我如何完成功能以实现我想要的功能?如果不是 - 我该怎么办呢?
答案 0 :(得分:1)
它可能更短,但这种方法首先计算排序键,然后用于对数组进行排序。
生成排序键非常明确且易于理解,这在创建排序算法时总能帮助我。
// sorting key = <year> + ('A' | 'B' | 'C')
function getitemkey(item)
{
var parts = item.match(/^(HT|VT)?(\d{4})$/);
switch (parts[1]) {
case 'VT': return parts[2] + 'A'; // VT goes first
case 'HT': return parts[2] + 'B'; // HT is second
}
return parts[2] + 'C'; // no prefix goes last
}
function cmp(a, b)
{
var ka = getitemkey(a),
kb = getitemkey(b);
// simple key comparison
if (ka > kb) {
return 1;
} else if (ka < kb) {
return -1;
}
return 0;
}
["HT2014", "VT2013", "2017", 'HT2013', '2013'].sort(cmp);
答案 1 :(得分:0)
我会使用带有捕获的正则表达式并对部分进行比较
function compare(a, b) {
var re = /([HV]T)?(\d\d\d\d)/;
var ma = re.exec(a);
var mb = re.exec(b);
// compare the years
if (ma[2] < mb[2])
return -1;
if (ma[2] > mb[2])
return 1;
// years are equal, now compare the prefixes
if (ma[1] == mb[1])
return 0;
if (ma[1] == 'VT')
return -1;
if (mb[1] == 'VT')
return 1;
if (ma[1] == 'HT')
return -1;
return 1;
}
答案 2 :(得分:0)
我会处理那个......
您可以通过从数组中获取最后一项而不是第二项来实现:
var lastCmp = as.pop() - bs.pop();
if (lastCmp) // != 0
return lastCmp;
else
// compare on as[0] / bs[0], though they might be undefined now
如何完成功能以完成我想要的工作?
您需要一个比较索引表。与@ Jack的switch
语句类似,它允许您声明自定义排序:
var orderingTable = {
"V": 1,
"H": 2
// …
},
def = 3;
var aindex = orderingTable[ as[0] ] || def, // by as[0]
bindex = orderingTable[ bs[0] ] || def; // by bs[0]
return aindex - bindex;
如果你不想要这样的表,你也可以使用数组:
var ordering = ["V", "H" /*…*/];
var *index = ordering.indexOf(*key)+1 || ordering.length+1;
答案 3 :(得分:0)
我冒昧地使用下划线:
var example_data = ["2002","HT2014", "VT2013", "2017", "VT2002", "HT2013"];
var split = _.groupBy(example_data, function(val){ return val.indexOf('T') === -1});
var justYears = split[true].sort();
var yearAndTerm = split[false].sort(function(a,b){
var regex = /([HV])T(\d\d\d\d)/;
var left = regex.exec(a);
var right = regex.exec(b);
return left[2].localeCompare(right[2]) || right[1].localeCompare(left[1]);
});
var sorted = yearAndTerm.concat(justYears);
console.log(sorted);
这是小提琴:http://jsfiddle.net/8KHGu/:)