1

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

var example_data = ["HT2014", "VT2013", "2017"];

我想对这个数组进行排序,使其主要按年份排序(即四位数字,作为数字),然后(如果年份相等)对其进行排序,使 VT 排在第一位,HT 位于中间并且未指定春季或秋季的条目是最后一个。

如果我sort()正确理解了 JavaScript 函数,我应该能够实现一个sortFunction告诉我两个对象中的哪一个应该是第一个,然后只需调用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"正确(除了可能是一系列荒谬的嵌套s...)。(另外,我知道上面的代码对于示例数据中的第三项会失败,因为只有 1 个元素。我会处理的......)"VT"""if"2017.split("T")

这是一个好方法吗?如果是 - 我如何完成功能来做我想做的事?如果没有 - 我应该怎么做?

4

4 回答 4

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);
于 2013-02-24T13:40:03.603 回答
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;
}
于 2013-02-24T13:39:46.843 回答
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;
于 2013-02-24T13:50:15.480 回答
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/ :)

于 2013-02-24T13:59:46.003 回答