1

春または秋を表すオプションの 2 文字の文字列と、その後に続く 4 桁の年で構成される文字列の配列があります。つまり、次の例のいずれかです。

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

この配列を主に年 (数字としての 4 桁) でソートし、次に (年が等しい場合) VT が最初、HT が真ん中、そして春または秋を指定しないエントリは最後です。

sort()JavaScript関数を正しく理解していればsortFunction、2 つのオブジェクトのどちらを先に実行するかを示す を実装してから、 を呼び出すことができるはず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"""ネストされた s のばかげたシリーズを除いてif...)。(また、上記のコードは、要素が 1 つしかないため、サンプル データの 3 番目の項目で失敗することもわかってい"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

私はそれを処理します...

2 番目の項目ではなく、配列から最後の項目を取得することで、これを行うことができます。

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 に答える