Javascript对字符串的一部分进行排序

时间:2013-02-24 13:22:23

标签: javascript sorting

我有一个字符串数组,其中包含一个可选的双字母字符串,表示春天或秋天,后面跟着一个四位数的年份,即作为以下示例之一:

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个元素。我会处理那个......)

这是一个好方法吗?如果是 - 我如何完成功能以实现我想要的功能?如果不是 - 我该怎么办呢?

4 个答案:

答案 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/:)