3

テキストを固定長に切り刻もうとしていますが、単語を半分に切り詰めたくないので、次のようにする必要があります。

function fixedLength(str, len, bol) {
    var i, l = str.length, left = 0, right = l - 1, rtn, tmp;

    tmp = str.charAt(len);

    if (bol || tmp === " " || tmp === "") {
        rtn = str.substr(0, len);
    } else {
        tmp = len - 1;

        for (i = tmp; i > -1; i--) {
            if (str.charAt(i) === " ") {
                left = i;
                break;
            }
        }

        for (i = tmp; i < l; i++) {
            if (str.charAt(i) === " ") {
                right = i;
                break;
            }
        }

        rtn = str.substr(0, ((Math.abs(left - tmp) <= Math.abs(right - tmp)) ? left : right));
    }

    return rtn + "...";
}

しかし、これを使用すると:

var str = "the quick brown fox jumped over the lazy dog";

for (var i = 0; i < 45; i++) {
    document.write("i:" + i + " - " + fixedLength(str, i) + "<br>");
}

この行を除いて、誰もが正しく動作しているように見え"i:43 - the quick brown fox jumped over the lazy do..."ます。「犬」という単語は半分に切り刻まれています (デモ)

欠陥が見つからない、何かを変更するたびに新しいバグを追加する

4

5 に答える 5

4

コードをチェックしませんでしたが、コードをもっと簡単に書くことができます:

function fixedLength(str, len, bol) {
    while(!bol && str[len] && str[len] !== ' ') {
      len--;
    }
    return str.substr(0, len) + '...';
}

そしてデモ

于 2012-06-24T05:51:05.990 に答える
1

正規表現を使用して最後のspace文字を見つけることができます。

function fixedLength(str, len, bol) {
    if(str.length <= len) {
       return str;  
    }

    var rtn = str.substr(0, len).match(/.* /);
    if(rtn == null) {
        rtn = "";
    } else {
        rtn = rtn + "...";
    }
    return rtn;
}

デモはこちら: http://jsfiddle.net/R8qMQ/2/

入力文字列がすでに最大許容長に達している場合は、単にそれを返すという検証も追加しました。分割できる単語がない場合は、NULL ではなく空の文字列を返します。

将来、単語区切り文字と見なす可能性のある他の文字を追加することもできるため、正規表現を使用します(たとえば.;またはおそらくREGEX b- 単語区切り文字)。

于 2012-06-24T06:01:52.817 に答える
1

ご参考までに、元のコードのバグは、tmp - left と tmp - right を比較した戻り値への最終代入にありました。問題は、文字列の最後の単語「dog」の場合、初期値が l - 1 に設定された後、right が再割り当てされないことです。そのため、アルゴリズムは、実際には ag があるのに、インデックス 44 でスペースが見つかったかのように動作します。

于 2012-06-24T06:17:38.420 に答える
0
rtn = str.substr(0, ((Math.abs(left - tmp + 1) <= Math.abs(right - tmp)) ? left : right));

デバッガーでデバッグしませんでしたが、デモを使用すると非常に役に立ちました。

于 2012-06-24T05:33:53.123 に答える
0

非常にわかりやすい方法でコードをリファクタリングしてみました。

function prettyCut(word, length) {
    //account for ellipses
    length -= 3;

    //break down into lengths
    var units = word.split(" ").map(function(word) {
        return word.length+1;
    });

    //map to accumulated sums
    var runningSum = 0;
    var sums = units.map(function(length, index) {
        return (runningSum += length)
    }); 

    //find difference from goal of each sum
    var differences = sums.map(function(sum) {
        return (length-sum)>0?(length-sum):100;
    });

    //minimize and return
    var closest = Math.min.apply(this, differences);
    return closest==0?word:word.substr(0, length-closest)+"...";
}
prettyCut("the quick brown fox jumped over the lazy dog", 45);
于 2012-06-24T05:46:43.380 に答える