重复字符串-Javascript

重复字符串-Javascript,javascript,string,Javascript,String,返回重复任意次数的字符串的最佳或最简洁的方法是什么 以下是我迄今为止的最佳拍摄: function repeat(s, n){ var a = []; while(a.length < n){ a.push(s); } return a.join(''); } 功能重复(s,n){ var a=[]; 而(a.长度>=1,模式+=模式; } 返回结果+模式; }; 或作为独立功能: function repeat(pattern, cou

返回重复任意次数的字符串的最佳或最简洁的方法是什么

以下是我迄今为止的最佳拍摄:

function repeat(s, n){
    var a = [];
    while(a.length < n){
        a.push(s);
    }
    return a.join('');
}
功能重复(s,n){
var a=[];
而(a.长度
函数重复(s,n){var r=”“;for(var a=0;a
请新读者注意:这个答案很老,也不太实用——它只是“聪明”,因为它使用数组的东西来获取
当我写“少处理”的时候,我的意思是
“更少的代码”是因为,正如其他人在随后的回答中所指出的,它
表现得像头猪。所以如果速度对你很重要,就不要使用它

我把这个函数直接放在String对象上。与其创建一个数组,填充它,然后用空字符连接它,不如创建一个长度合适的数组,然后用你想要的字符串连接它。同样的结果,更少的过程

String.prototype.repeat = function( num )
{
    return new Array( num + 1 ).join( this );
}

alert( "string to repeat\n".repeat( 4 ) );
这是如何使用delimeter将字符串重复几次。

展开:

这样,您就可以避免意外的参数类型:

var foo = 'bar';
alert(foo.repeat(3));              // Will work, "barbarbar"
alert(foo.repeat('3'));            // Same as above
alert(foo.repeat(true));           // Same as foo.repeat(1)

alert(foo.repeat(0));              // This and all the following return an empty
alert(foo.repeat(false));          // string while not causing an exception
alert(foo.repeat(null));
alert(foo.repeat(undefined));
alert(foo.repeat({}));             // Object
alert(foo.repeat(function () {})); // Function

编辑:感谢他优雅的
++num
想法!

这一个非常有效

String.prototype.repeat = function(times){
    var result="";
    var pattern=this;
    while (times > 0) {
        if (times&1)
            result+=pattern;
        times>>=1;
        pattern+=pattern;
    }
    return result;
};

我已经测试了所有建议方法的性能

这是我得到的最快的变体

String.prototype.repeat = function(count) {
    if (count < 1) return '';
    var result = '', pattern = this.valueOf();
    while (count > 1) {
        if (count & 1) result += pattern;
        count >>= 1, pattern += pattern;
    }
    return result + pattern;
};
String.prototype.repeat=函数(计数){
如果(计数<1)返回“”;
var result='',pattern=this.valueOf();
而(计数>1){
如果(计数&1)结果+=模式;
计数>>=1,模式+=模式;
}
返回结果+模式;
};
或作为独立功能:

function repeat(pattern, count) {
    if (count < 1) return '';
    var result = '';
    while (count > 1) {
        if (count & 1) result += pattern;
        count >>= 1, pattern += pattern;
    }
    return result + pattern;
}
function repeat(s, n) {
  var str = '';
  for (var i = 0; i < n; i++) {
    str += s;
  }
  return str;
}
功能重复(模式、计数){
如果(计数<1)返回“”;
var结果=“”;
而(计数>1){
如果(计数&1)结果+=模式;
计数>>=1,模式+=模式;
}
返回结果+模式;
}
它是基于算法的。 它真的很快。而且
计数越大
,与传统的
新数组(计数+1).连接(字符串)
方法相比,它的速度就越快

我只改变了两件事:

  • pattern=this
    替换为
    pattern=this.valueOf()
    (清除一个明显的类型转换)
  • 添加了
    if(count<1)
    check from to the top of function,以排除这种情况下不必要的操作
  • 从(5-7%的速度提升)开始应用优化
  • UPD

    为感兴趣的人创建了一个小型性能测试平台

    变量
    计数
    ~0..100:

    常数
    计数
    =1024:


    如果可以,请使用它并使其更快:)

    这可能是最小的递归:-

    String.prototype.repeat = function(n,s) {
    s = s || ""
    if(n>0) {
       s += this
       s = this.repeat(--n,s)
    }
    return s}
    

    使用分治的递归解决方案:

    function repeat(n, s) {
        if (n==0) return '';
        if (n==1 || isNaN(n)) return s;
        with(Math) { return repeat(floor(n/2), s)+repeat(ceil(n/2), s); }
    }
    

    各种方法的试验:

    var repeatMethods = {
        control: function (n,s) {
            /* all of these lines are common to all methods */
            if (n==0) return '';
            if (n==1 || isNaN(n)) return s;
            return '';
        },
        divideAndConquer:   function (n, s) {
            if (n==0) return '';
            if (n==1 || isNaN(n)) return s;
            with(Math) { return arguments.callee(floor(n/2), s)+arguments.callee(ceil(n/2), s); }
        },
        linearRecurse: function (n,s) {
            if (n==0) return '';
            if (n==1 || isNaN(n)) return s;
            return s+arguments.callee(--n, s);
        },
        newArray: function (n, s) {
            if (n==0) return '';
            if (n==1 || isNaN(n)) return s;
            return (new Array(isNaN(n) ? 1 : ++n)).join(s);
        },
        fillAndJoin: function (n, s) {
            if (n==0) return '';
            if (n==1 || isNaN(n)) return s;
            var ret = [];
            for (var i=0; i<n; i++)
                ret.push(s);
            return ret.join('');
        },
        concat: function (n,s) {
            if (n==0) return '';
            if (n==1 || isNaN(n)) return s;
            var ret = '';
            for (var i=0; i<n; i++)
                ret+=s;
            return ret;
        },
        artistoex: function (n,s) {
            var result = '';
            while (n>0) {
                if (n&1) result+=s;
                n>>=1, s+=s;
            };
            return result;
        }
    };
    function testNum(len, dev) {
        with(Math) { return round(len+1+dev*(random()-0.5)); }
    }
    function testString(len, dev) {
        return (new Array(testNum(len, dev))).join(' ');
    }
    var testTime = 1000,
        tests = {
            biggie: { str: { len: 25, dev: 12 }, rep: {len: 200, dev: 50 } },
            smalls: { str: { len: 5, dev: 5}, rep: { len: 5, dev: 5 } }
        };
    var testCount = 0;
    var winnar = null;
    var inflight = 0;
    for (var methodName in repeatMethods) {
        var method = repeatMethods[methodName];
        for (var testName in tests) {
            testCount++;
            var test = tests[testName];
            var testId = methodName+':'+testName;
            var result = {
                id: testId,
                testParams: test
            }
            result.count=0;
    
            (function (result) {
                inflight++;
                setTimeout(function () {
                    result.start = +new Date();
                    while ((new Date() - result.start) < testTime) {
                        method(testNum(test.rep.len, test.rep.dev), testString(test.str.len, test.str.dev));
                        result.count++;
                    }
                    result.end = +new Date();
                    result.rate = 1000*result.count/(result.end-result.start)
                    console.log(result);
                    if (winnar === null || winnar.rate < result.rate) winnar = result;
                    inflight--;
                    if (inflight==0) {
                        console.log('The winner: ');
                        console.log(winnar);
                    }
                }, (100+testTime)*testCount);
            }(result));
        }
    }
    
    var repeatMethods={
    控制:功能(n,s){
    /*所有这些行对于所有方法都是通用的*/
    如果(n==0)返回“”;
    如果(n==1 | | isNaN(n))返回s;
    返回“”;
    },
    分割与征服:函数(n,s){
    如果(n==0)返回“”;
    如果(n==1 | | isNaN(n))返回s;
    with(Math){return arguments.callee(floor(n/2),s)+arguments.callee(ceil(n/2),s);}
    },
    线性诅咒:函数(n,s){
    如果(n==0)返回“”;
    如果(n==1 | | isNaN(n))返回s;
    返回s+参数。被调用方(--n,s);
    },
    newArray:函数(n,s){
    如果(n==0)返回“”;
    如果(n==1 | | isNaN(n))返回s;
    返回(新数组(isNaN(n)?1:++n)).join(s);
    },
    fillAndJoin:函数(n,s){
    如果(n==0)返回“”;
    如果(n==1 | | isNaN(n))返回s;
    var-ret=[];
    对于(var i=0;i>=1,s+=s;
    };
    返回结果;
    }
    };
    函数testNum(len,dev){
    使用(Math){returnround(len+1+dev*(random()-0.5));}
    }
    函数testString(len,dev){
    返回(新数组(testNum(len,dev))).join(“”);
    }
    var testTime=1000,
    测试={
    大人物:{str:{len:25,dev:12},rep:{len:200,dev:50},
    smalls:{str:{len:5,dev:5},rep:{len:5,dev:5}
    };
    var-testCount=0;
    var-winnar=null;
    飞行中的风险=0;
    for(repeatMethods中的var methodName){
    var method=repeatMethods[methodName];
    for(测试中的var testName){
    testCount++;
    var test=测试[testName];
    var testId=methodName+':'+testName;
    var结果={
    id:testId,
    testParams:test
    }
    结果:计数=0;
    (功能(结果){
    机上++;
    setTimeout(函数(){
    result.start=+新日期();
    while((new Date()-result.start)
    这是JSLint的安全版本

    String.prototype.repeat = function (num) {
      var a = [];
      a.length = num << 0 + 1;
      return a.join(this);
    };
    
    String.prototype.repeat=函数(num){
    var a=[];
    
    a、 length=num这比disfated的答案提高了5-7%

    通过停止在
    count>1
    处展开循环,并在循环后执行额外的
    result+=pattnern
    concat。这将避免循环最终之前未使用的
    pattern+=pattern
    ,而无需使用昂贵的if检查。 最终结果如下所示:

    String.prototype.repeat = function(count) {
        if (count < 1) return '';
        var result = '', pattern = this.valueOf();
        while (count > 1) {
            if (count & 1) result += pattern;
            count >>= 1, pattern += pattern;
        }
        result += pattern;
        return result;
    };
    
    String.prototype.repeat=函数(计数){
    如果(计数<1)返回“”;
    变量结果=“”,模式=
    
    String.prototype.repeat = function (num) {
      var a = [];
      a.length = num << 0 + 1;
      return a.join(this);
    };
    
    String.prototype.repeat = function(count) {
        if (count < 1) return '';
        var result = '', pattern = this.valueOf();
        while (count > 1) {
            if (count & 1) result += pattern;
            count >>= 1, pattern += pattern;
        }
        result += pattern;
        return result;
    };
    
    for (var i = 0, result = ''; i < N; i++) result += S;
    
    // repeated string
    var string = '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789';
    // count paremeter is changed on every test iteration, limit it's maximum value here
    var maxCount = 200;
    
    var n = 0;
    $.each(tests, function (name) {
        var fn = tests[name];
        JSLitmus.test(++n + '. ' + name, function (count) {
            var index = 0;
            while (count--) {
                fn.call(string.slice(0, index % string.length), index % maxCount);
                index++;
            }
        });
        if (fn.call('>', 10).length !== 10) $('body').prepend('<h1>Error in "' + name + '"</h1>');
    });
    
    JSLitmus.runAll();
    
    // final: growing pattern + prototypejs check (count < 1)
    'final avoid': function (count) {
        if (!count) return '';
        if (count == 1) return this.valueOf();
        var pattern = this.valueOf();
        if (count == 2) return pattern + pattern;
        if (count == 3) return pattern + pattern + pattern;
        var result;
        if (count & 1) result = pattern;
        else result = '';
        count >>= 1;
        do {
            pattern += pattern;
            if (count & 1) result += pattern;
            count >>= 1;
        } while (count > 1);
        return result + pattern + pattern;
    }
    
    String.prototype.repeat = function(num) {
        num = parseInt(num);
        if (num < 0) return '';
        return new Array(num + 1).join(this);
    }
    
    /*
     * Usage: stringFill3("abc", 2) == "abcabc"
     */
    
    function stringFill3(x, n) {
        var s = '';
        for (;;) {
            if (n & 1) s += x;
            n >>= 1;
            if (n) x += x;
            else break;
        }
        return s;
    }
    
    function stringFill1(x, n) { 
        var s = ''; 
        while (s.length < n) s += x; 
        return s; 
    } 
    /* Example of output: stringFill1('x', 3) == 'xxx' */ 
    
    function stringFill2(x, n) { 
        var s = ''; 
        while (n-- > 0) s += x; 
        return s; 
    } 
    
    function testFill(functionToBeTested, outputSize) { 
        var i = 0, t0 = new Date(); 
        do { 
            functionToBeTested('x', outputSize); 
            t = new Date() - t0; 
            i++; 
        } while (t < 2000); 
        return t/i/1000; 
    } 
    seconds1 = testFill(stringFill1, 100); 
    seconds2 = testFill(stringFill2, 100); 
    
    x = 'x'; 
    s = ''; 
    s += x; /* Now s = 'x' */ 
    x += x; /* Now x = 'xx' */ 
    x += x; /* Now x = 'xxxx' */ 
    x += x; /* Now x = 'xxxxxxxx' */ 
    s += x; /* Now s = 'xxxxxxxxx' as desired */
    
    function stringFill3(x, n) { 
        var s = ''; 
        for (;;) { 
            if (n & 1) s += x; 
            n >>= 1; 
            if (n) x += x; 
            else break; 
        } 
        return s; 
    } 
    
    function repeat(s, n){
        return ((new Array(n+1)).join(s));
    }
    alert(repeat('R', 10));
    
    function ditto( s, r, c ) {
        return c-- ? ditto( s, r += s, c ) : r;
    }
    
    ditto( "foo", "", 128 );
    
    String.prototype.ditto = function( c ) {
        return --c ? this + this.ditto( c ) : this;
    };
    
    "foo".ditto( 128 );
    
    String.prototype.ditto = function() {
        var c = Number( arguments[ 0 ] ) || 2,
            r = this.valueOf();
        while ( --c ) {
            r += this;
        }
        return r;
    }
    
    "foo".ditto();
    
    "yo".repeat(2);
    // returns: "yoyo"
    
    String.prototype.repeat = String.prototype.repeat || function(n){
        return n<=1 ? this : this.concat(this.repeat(n-1));
    }
    
    'abc'.repeat(3); //abcabcabc
    
    > _.repeat('yo', 2)
    "yoyo"
    
    function repeat(s, n) { return new Array(n+1).join(s); }
    
    function repeat(s, n) { var a=[],i=0;for(;i<n;)a[i++]=s;return a.join(''); }
    
    function repeat(s,n) { return s.repeat(n) };
    
    function repeat(pattern, count) {
      for (var result = '';;) {
        if (count & 1) {
          result += pattern;
        }
        if (count >>= 1) {
          pattern += pattern;
        } else {
          return result;
        }
      }
    }
    
    function concatStr(str, num) {
       var arr = [];
    
       //Construct an array
       for (var i = 0; i < num; i++)
          arr[i] = str;
    
       //Join all elements
       str = arr.join('');
    
       return str;
    }
    
    console.log(concatStr("abc", 3));
    
    function repeat(s, n) {
      var str = '';
      for (var i = 0; i < n; i++) {
        str += s;
      }
      return str;
    }
    
    var str = 'cat';
    var num = 23;
    var size = str.length * num;
    "".padStart(size, str) // outputs: 'catcatcatcatcatcatcatcatcatcatcatcatcatcatcatcatcatcatcatcatcatcatcat'