为什么我的话被切成两半?

时间:2012-06-24 05:23:35

标签: javascript string chop

我想把文字剪成一个固定的长度,但我不想把文字切成两半,所以我需要做这样的事情:

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..."中,“狗”一词被切成两半(Demo

我无法找到这个缺陷,每次我改变一些东西,我都会添加一个新的错误

5 个答案:

答案 0 :(得分:4)

没有检查您的代码,但您可以更简单地编写代码:

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

demo

答案 1 :(得分: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 - 字分隔符)

答案 2 :(得分:1)

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

答案 3 :(得分:0)

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

我没有使用调试器调试它,但使用Demo非常有帮助。

答案 4 :(得分: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);