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。

我会使用正则表达式,因为将来我还可以添加其他我可能认为是单词分隔符的字符(例如.,或者;可能是正则表达式b- 单词分隔符)。

于 2012-06-24T06:01:52.817 回答
1

如果您有兴趣,原始代码中的错误是在对返回值的最终分配中,您在其中比较了 tmp - left 和 tmp - right。问题在于,对于字符串中的最后一个单词“dog”,在其初始值设置为 l - 1 后,权利永远不会被重新分配;所以你的算法就好像在索引 44 找到了一个空格,而实际上那里有 ag。

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

我没有使用调试器对其进行调试,但使用您的Demo非常有帮助。

于 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 回答