0

現在取り組んでいるプロジェクトの要件がありますが、これは少し注意が必要です。

Text基本的に、これらのアイテムのプロパティに基づいてアイテムの配列を並べ替える必要があります。

これが私のアイテムです:

var answers = [],
    answer1 = { Id: 1, Text: '3-4 weeks ago' },
    answer2 = { Id: 2, Text: '1-2 weeks ago' },
    answer3 = { Id: 3, Text: '7-8 weeks ago' },
    answer4 = { Id: 4, Text: '5-6 weeks ago' },
    answer5 = { Id: 5, Text: '1-2 days ago' },
    answer6 = { Id: 6, Text: 'More than 1 month ago' };

answers.push(answer1);
answers.push(answer2);
answers.push(answer3);
answers.push(answer4);
answers.push(answer5);
answers.push(answer6);

各アイテムのプロパティを分析してText、並べ替え後の配列が次のようになるようにする必要があります。

answers[0] = { Id: 6, Text: 'More than 1 month ago' }
answers[1] = { Id: 3, Text: '7-8 weeks ago' }
answers[2] = { Id: 4, Text: '5-6 weeks ago' }
answers[3] = { Id: 1, Text: '3-4 weeks ago' }
answers[4] = { Id: 2, Text: '1-2 weeks ago' }
answers[5] = { Id: 5, Text: '1-2 days ago' }

論理的には、日付が遠いほど優先度が高くなるため、配列の最初に表示されるはずです。したがって、「1〜2日」は、「7〜8週間」よりも優先度が低くなります。

つまり、論理的には、数値を抽出してから、単位(日、週など)を抽出し、それらの詳細に基づいて配列を並べ替える必要があります。

正直なところ、解決策を見つけるのは非常に難しいと感じています。助けていただければ幸いです。

編集:私が扱っているデータに関しては、それはWebサービスから戻ってきており、テキストを変更することはできません。ですから、そのまま使用する必要があります。

4

2 に答える 2

2

ここで説明するように、テキストから値を解析し、それらを数値で比較するカスタムソート関数を使用できます。

var answers = [
    { Id: 1, Text: '3-4 weeks ago' },
    { Id: 2, Text: '1-2 weeks ago' },
    { Id: 3, Text: '7-8 weeks ago' },
    { Id: 4, Text: '5-6 weeks ago' },
    { Id: 5, Text: '1-2 days ago' },
    { Id: 6, Text: 'More than 1 month ago' }
];

answers.sort(function(a, b) {
    function getVal(item) {
        var val;
        // find first number
        var match = item.Text.match(/\d+/);
        if (match) {
            val = parseInt(match[0], 10);
        } else {
            val = 10000;   // set to very high number
        }
        if (item.Text.indexOf("More than") !== -1) {
            ++val;
        }
        if (item.Text.indexOf("week") !== -1) {
            val *= 7;
        } else if (item.Text.indexOf("month") !== -1) {
            val *= 30;
        }
        return(val);
    }
    return(getVal(b) - getVal(a));
});

作業デモ: http: //jsfiddle.net/jfriend00/cf3D7/

getVal()必要な解析ロジックをサポートするように関数を微調整できることは明らかです。

配列が大きい場合は、並べ替えインデックスを事前に計算して各オブジェクトに格納することでパフォーマンスを向上させることができます。これにより、カスタムの並べ替え関数は、毎回再計算するのではなく、2つの数値を直接比較します。ただし、配列は100項目未満であり、おそらく無関係です。

また、「1か月以上前」と「7〜8週間」をどのように分類するかが明確ではありません。私の現在のアルゴリズムは「1か月以上前」を1か月として扱いますが、特定のルールを念頭に置いている場合は、解析ロジックを微調整できます。カスタムの並べ替え関数を使用すると、並べ替えロジックの鍵はすべて、getVal()サポートしたい構文をサポートするように調整できる関数の実装にあります。

これは、sortKeyを事前に計算して、大きな配列に対してはるかに優れたパフォーマンスを発揮するバージョンです。

(function() {
    function getVal(item) {
        var val;
        // find first number
        var match = item.Text.match(/\d+/);
        if (match) {
            val = parseInt(match[0], 10);
        } else {
            val = 10000;   // set to very high number
        }
        if (item.Text.indexOf("More than") !== -1) {
            ++val;
        }
        if (item.Text.indexOf("week") !== -1) {
            val *= 7;
        } else if (item.Text.indexOf("month") !== -1) {
            val *= 30;
        }
        return(val);
    }

    for (var i = 0, len = answers.length; i < len; i++) {
        answers[i].sortKey = getVal(answers[i]);
    }
    answers.sort(function(a, b) {
        return(b.sortKey - a.sortKey);
    });
})()

PSjsFiddleで使用したはるかに効率的な配列宣言構文に注意してください。

于 2012-11-22T17:00:11.717 に答える
0

良い方法だと思いますが、indexOf()メソッドを使用して、配列内の各要素で月、日、週などの単語を検索し、その後indexOfを使用して数値を検索します。テキストを抽出するには、部分文字列を使用できます。たとえば、文字列「1〜2週間前」の場合、str.substring(0、indexOf'-')と言うと、最初の文字からダッシュまですべてが取得されます。したがって、3桁または4桁の数字であっても、最初の数字を抽出します。(「-」文字もキャッチする可能性があるため、indexOf('-')-1 ..である必要があります。)

これを行う良い方法は、時間の最大単位を配列で検索します。「年」が含まれるものを探します。見つからない場合は、月を検索します。次に、一時的な配列を作成し、を含むすべての要素をコピーします。現在探している時間の単位。したがって、たとえば、年を検索し、何も検索せず、月を検索し、month(s)という単語を含む1つの要素を検索し、それをtemp配列に移動します。次に、一時配列内のすべての要素を分析し、最大数の要素を見つけます。したがって、あなたの例の場合、あなたは1つしか持っていないでしょうが、あなたの答えは次のように見えたと言います

answer1 = { Id: 1, Text: '3-4 weeks ago' },
answer2 = { Id: 2, Text: '1-2 weeks ago' },
answer3 = { Id: 3, Text: '7-8 weeks ago' },
answer4 = { Id: 4, Text: '6 months ago' },
answer5 = { Id: 5, Text: '5-6 weeks ago' },
answer6 = { Id: 6, Text: '1-2 days ago' },
answer7 = { Id: 7, Text: ' 1 month ago' };
answer8 = { Id: 8, Text: ' 3 months ago' };

次に、月単位で3つの要素があり、3つすべてを調べて、数に基づいて並べ替えます。つまり、6か月、3か月、1か月です。次に、ソートされた3番目の最後の配列、またはメイン配列を再配置します。新しい「ソート済み」配列の方がうまくいくと思います。したがって、月単位のこれら3つの要素を、新しい並べ替えられた配列に配置します。

次に、週に移動し、週のある4つの要素を見つけて、それらを一時配列に移動し、それらの数値を分析し、サイズ順に並べてから、並べ替えられた配列に貼り付けてから、日に移動します。等..

とにかく少しhtp

于 2012-11-22T17:12:42.067 に答える