Suggestion: Array.prototype.repeat

# Axel Rauschmayer (13 years ago)

Array.prototype.repeat seems like a logical dual to String.prototype.repeat: harmony:string.prototype.repeat

Implementation:

Array.prototype.repeat = function (times) {
    var result = [];
    var len = this.length;
    var resultLen = len * times;
    for(var i = 0; i < resultLen; i++) {
        result.push(this[i % len]);
    }
    return result;
}

In use:

$ [1,2,3].repeat(3)
[ 1,  2,  3,  1,  2,  3,  1,  2,  3 ]
# Mariusz Nowak (13 years ago)

I like it, it indeed looks very logical, however it's a bit controversial that we need to create temporary array object to get one that we want. Function (not method) that returns generated array may make more sense, currently I'm using something like that:

var slice = Array.prototype.slice;

Array.generate = function (length, fill) { var arr, l; length = length >>> 0; if (arguments.length < 2) { throw new TypeError("Cannot generarte an array without provided fill."); } arr = slice.call(arguments, 1, 1 + length); while ((l = arr.length) < length) { arr = arr.concat(arr.slice(0, length - l)); } return arr; };

( medikoo/es5-ext/blob/master/lib/Array/generate.js )

# Michael A. Smith (13 years ago)

On Mon, Jan 2, 2012 at 3:56 PM, Mariusz Nowak <medikoo+mozilla.org at medikoo.com> wrote:

I like it, it indeed looks very logical, however it's a bit controversial that we need to create temporary array object to get one that we want. Function (not method) that returns generated array may make more sense…

Is the difference in overhead between instantiating a new array and using Array.prototype.slice.call on arguments really worth sacrificing consistency with the proposed string.prototype.repeat and the very clean syntax of someArray.repeat(n)?

Michael A. Smith Web Developer True Action Network (an eBay company)

# Adam Shannon (13 years ago)

Another thing to think about is that .repeat (both on String and Array) will be used a lot in production. So it would make sense for each solution to be optimized for their specific case. It doesn't make sense to slow down something as trivial as .repeat()

# Rick Waldron (13 years ago)

On Mon, Jan 2, 2012 at 3:56 PM, Mariusz Nowak < medikoo+mozilla.org at medikoo.com> wrote:

I like it, it indeed looks very logical, however it's a bit controversial that we need to create temporary array object to get one that we want.

Is the controversy editorial or fact, because the following methods are all specified to use a temporary, newly initialized Array internally:

Array.prototype.concat Array.prototype.filter Array.prototype.map Array.prototype.slice Array.prototype.splice

String.prototype.match String.prototype.split

RegExp.prototype.exec

Object.getOwnPropertyNames Object.keys

Function (not method) that returns generated array may make more sense, currently I'm using something like that:

var slice = Array.prototype.slice;

Array.generate = function (length, fill) { var arr, l; length = length >>> 0; if (arguments.length < 2) { throw new TypeError("Cannot generarte an array without provided fill."); } arr = slice.call(arguments, 1, 1 + length); while ((l = arr.length) < length) { arr = arr.concat(arr.slice(0, length - l)); } return arr; };

This doesn't produce the same as Array.prototype.repeat..

// regular console.log( Array.generate( 3, [1,2,3] ) ); // sparse console.log( Array.generate( 3, [1,2,,3] ) );

[ [ 1, 2, 3 ], [ 1, 2, 3 ], [ 1, 2, 3 ] ] [ [ 1, 2, , 3 ], [ 1, 2, , 3 ], [ 1, 2, , 3 ] ]

# Rick Waldron (13 years ago)

On Mon, Jan 2, 2012 at 5:55 PM, Adam Shannon <adam at ashannon.us> wrote:

Another thing to think about is that .repeat (both on String and Array) will be used a lot in production. So it would make sense for each solution to be optimized for their specific case. It doesn't make sense to slow down something as trivial as .repeat()

Creating a 10000 item array by repeating a 1000 item array 10 times, the difference is negligible when compared the implementation that I wrote, not the one given above

jsperf.com/array-repeat/2

Also, note that I had to "make up" my own Array.repeat() because the Array.generate shown above did not create the same return as the initial Array.prototype.repeat(), but I stuck to the concepts laid out - no new array is initialized (except that Array.prototype.slice does initialize a new Array() ).

# Mariusz Nowak (13 years ago)

Rick Waldron wrote:

On Mon, Jan 2, 2012 at 3:56 PM, Mariusz Nowak < medikoo+mozilla.org at medikoo.com> wrote:

I like it, it indeed looks very logical, however it's a bit controversial that we need to create temporary array object to get one that we want.

Is the controversy editorial or fact, because the following methods are all specified to use a temporary, newly initialized Array internally:

Array.prototype.concat Array.prototype.filter (...)

Rick, you say that apart of output arrays this methods create some other temporary arrays internally ? I don't see anything like that in specification, where exactly is it stated ?

This doesn't produce the same as Array.prototype.repeat..

// regular console.log( Array.generate( 3, [1,2,3] ) ); // sparse console.log( Array.generate( 3, [1,2,,3] ) );

[ [ 1, 2, 3 ], [ 1, 2, 3 ], [ 1, 2, 3 ] ] [ [ 1, 2, , 3 ], [ 1, 2, , 3 ], [ 1, 2, , 3 ] ]

It is supposed to be used that way: Array.generate(4, 1, 2, 3) // -> [1, 2, 3, 1];

Usage you suggested as with Array.prototype.repeat will imply need of creating temporary array object.

# Herby Vojčík (13 years ago)

Hello,

binary ftw. See jsperf.com/array-repeat/4 Array.prototype.repeatD. And I also tried push.apply in repeatC (not to copy over the array using concat but grow it in place until possible) and it really surprised me it was that much slower. Concat is probably heavily optimized.

Herby

-----Pôvodná správa---

# felix (13 years ago)

repeatD(10) returns 17 copies, not 10.

# Rick Waldron (13 years ago)

On Tue, Jan 3, 2012 at 3:34 AM, Mariusz Nowak < medikoo+mozilla.org at medikoo.com> wrote:

Rick Waldron wrote:

On Mon, Jan 2, 2012 at 3:56 PM, Mariusz Nowak < medikoo+mozilla.org at medikoo.com> wrote:

I like it, it indeed looks very logical, however it's a bit controversial

that we need to create temporary array object to get one that we want.

Is the controversy editorial or fact, because the following methods are all specified to use a temporary, newly initialized Array internally:

Array.prototype.concat Array.prototype.filter (...)

Rick, you say that apart of output arrays this methods create some other temporary arrays internally ? I don't see anything like that in specification, where exactly is it stated ?

Array.prototype.concat

Array.prototype.filter

Array.prototype.map

Array.prototype.slice

Array.prototype.splice

String.prototype.match

String.prototype.split

RegExp.prototype.exec

Object.getOwnPropertyNames

Object.keys

This doesn't produce the same as Array.prototype.repeat..

// regular console.log( Array.generate( 3, [1,2,3] ) ); // sparse console.log( Array.generate( 3, [1,2,,3] ) );

[ [ 1, 2, 3 ], [ 1, 2, 3 ], [ 1, 2, 3 ] ] [ [ 1, 2, , 3 ], [ 1, 2, , 3 ], [ 1, 2, , 3 ] ]

It is supposed to be used that way: Array.generate(4, 1, 2, 3) // -> [1, 2, 3, 1];

Got it, I misunderstood, as there was no example usage - thanks for clarifying.

# Herby Vojčík (13 years ago)

Sorry, fixed (you get the idea, anyway, doing 10 concats is worse than doing five of them, with big chunks of data in the last calls). There is a checking throw in the end so it really works now. Now it is even more faster :-)

Herby

-----Pôvodná správa---

# Mariusz Nowak (13 years ago)

Rick Waldron wrote:

On Tue, Jan 3, 2012 at 3:34 AM, Mariusz Nowak < medikoo+mozilla.org at medikoo.com> wrote:

Rick Waldron wrote:

On Mon, Jan 2, 2012 at 3:56 PM, Mariusz Nowak < medikoo+mozilla.org at medikoo.com> wrote:

I like it, it indeed looks very logical, however it's a bit controversial

that we need to create temporary array object to get one that we want.

Is the controversy editorial or fact, because the following methods are all specified to use a temporary, newly initialized Array internally:

Array.prototype.concat Array.prototype.filter (...)

Rick, you say that apart of output arrays this methods create some other temporary arrays internally ? I don't see anything like that in specification, where exactly is it stated ?

Array.prototype.concat

Array.prototype.filter

(...)

Rick, those arrays become result of each method, they're not temporary.


Mariusz Nowak

medikoo

# Rick Waldron (13 years ago)

On Tue, Jan 3, 2012 at 9:19 AM, Mariusz Nowak < medikoo+mozilla.org at medikoo.com> wrote:

Rick Waldron wrote:

On Tue, Jan 3, 2012 at 3:34 AM, Mariusz Nowak < medikoo+mozilla.org at medikoo.com> wrote:

Rick Waldron wrote:

On Mon, Jan 2, 2012 at 3:56 PM, Mariusz Nowak < medikoo+mozilla.org at medikoo.com> wrote:

I like it, it indeed looks very logical, however it's a bit controversial

that we need to create temporary array object to get one that we want.

Is the controversy editorial or fact, because the following methods are

all specified to use a temporary, newly initialized Array internally:

Array.prototype.concat Array.prototype.filter (...)

Rick, you say that apart of output arrays this methods create some other temporary arrays internally ? I don't see anything like that in specification, where exactly is it stated ?

Array.prototype.concat

Array.prototype.filter

(...)

Rick, those arrays become result of each method, they're not temporary.

Sorry, I should've been clearer... I was responding to your statement that implied Axel's example code was somehow creating an unnecessary temporary array - have I missed something here?

# Greg Smith (13 years ago)

What is the use case for .repeat? Trying to imagine some code where I'd need it so I can get a feel for how it should work.

# Mariusz Nowak (13 years ago)

Rick Waldron wrote:

On Tue, Jan 3, 2012 at 9:19 AM, Mariusz Nowak < medikoo+mozilla.org at medikoo.com> wrote:

Rick Waldron wrote:

On Tue, Jan 3, 2012 at 3:34 AM, Mariusz Nowak < medikoo+mozilla.org at medikoo.com> wrote:

Rick Waldron wrote:

On Mon, Jan 2, 2012 at 3:56 PM, Mariusz Nowak < medikoo+mozilla.org at medikoo.com> wrote:

I like it, it indeed looks very logical, however it's a bit controversial

that we need to create temporary array object to get one that we want.

Is the controversy editorial or fact, because the following methods are

all specified to use a temporary, newly initialized Array internally:

Array.prototype.concat Array.prototype.filter (...)

Rick, you say that apart of output arrays this methods create some other

temporary arrays internally ? I don't see anything like that in specification, where exactly is it stated ?

Array.prototype.concat

Array.prototype.filter

(...)

Rick, those arrays become result of each method, they're not temporary.

Sorry, I should've been clearer... I was responding to your statement that implied Axel's example code was somehow creating an unnecessary temporary array - have I missed something here?

Rick, what I meant is that it implies creation of temporary array object. Let's say I want to have an array made of numbers 1,2,3 repeated three times. To get it I need to create temporary [1, 2, 3] array which I don't really need: result = [1, 2, 3].repeat(3);

It'll be more clean if it will work directly on context array:

var x = [1, 2, 3]; x.repeat(2); console.log(x); // [1, 2, 3, 1, 2, 3];

but that probably won't be expected behavior by most developers.

Anyway as Greg pointed, it's hard to find a valid use case for any array repeating method, it conceptually may look as nice add-on, but I'm not sure if it would be that useful to have it in standard.

# Rick Waldron (13 years ago)

On Tue, Jan 3, 2012 at 10:16 AM, Mariusz Nowak < medikoo+mozilla.org at medikoo.com> wrote:

Rick Waldron wrote:

On Tue, Jan 3, 2012 at 9:19 AM, Mariusz Nowak < medikoo+mozilla.org at medikoo.com> wrote:

Rick Waldron wrote:

On Tue, Jan 3, 2012 at 3:34 AM, Mariusz Nowak < medikoo+mozilla.org at medikoo.com> wrote:

Rick Waldron wrote:

On Mon, Jan 2, 2012 at 3:56 PM, Mariusz Nowak < medikoo+mozilla.org at medikoo.com> wrote:

I like it, it indeed looks very logical, however it's a bit controversial

that we need to create temporary array object to get one that we want.

Is the controversy editorial or fact, because the following methods are

all specified to use a temporary, newly initialized Array internally:

Array.prototype.concat Array.prototype.filter (...)

Rick, you say that apart of output arrays this methods create some other

temporary arrays internally ? I don't see anything like that in specification, where exactly is it stated ?

Array.prototype.concat

Array.prototype.filter

(...)

Rick, those arrays become result of each method, they're not temporary.

Sorry, I should've been clearer... I was responding to your statement that implied Axel's example code was somehow creating an unnecessary temporary array - have I missed something here?

Rick, what I meant is that it implies creation of temporary array object. Let's say I want to have an array made of numbers 1,2,3 repeated three times. To get it I need to create temporary [1, 2, 3] array which I don't really need: result = [1, 2, 3].repeat(3);

It'll be more clean if it will work directly on context array:

var x = [1, 2, 3]; x.repeat(2); console.log(x); // [1, 2, 3, 1, 2, 3];

but that probably won't be expected behavior by most developers.

Thanks for clarifying - I had been under the impression that you were referring to the implementation details specifically.

Anyway as Greg pointed, it's hard to find a valid use case for any array repeating method, it conceptually may look as nice add-on, but I'm not sure if it would be that useful to have it in standard.

+1

# Nadav Shesek (13 years ago)

Sorry - I had my email address misconfigured so it rejected my email. Sending it again: