Array.prototype.repeat

# Cyril Auburtin (25 days ago)

String and Array share a few methods.

I think repeat could exist for Array as well

At the moment, there are other more verbose ways to do so:

  • Array.from({length: n}, () => 'foo')
  • Array(n).fill('foo')
  • [].concat(...Array.from({length: 3}, () => ['x', 'y']))
  • [].concat(...Array(3).fill(['x', 'y']))

so with repeat it would just be;

  • ['foo'].repeat(n)
  • ['x', 'y'].repeat(3)
# Peter Jaszkowiak (25 days ago)

I'm guessing this would be an appropriate polyfill:

Array.prototype.repeat = function repeat(count) {
  let output = this;
  while (--count) {
    output = output.concat(this);
  }
  return output;
};
# Claude Pache (25 days ago)

Le 25 mars 2018 à 20:27, Cyril Auburtin <cyril.auburtin at gmail.com> a écrit :

String and Array share a few methods.

I think repeat could exist for Array as well

At the moment are other more verbose ways to do so:

  • Array.from({length: n}, () => 'foo')
  • Array(n).fill('foo')
  • [].concat(...Array.from({length: 3}, () => ['x', 'y']))
  • [].concat(...Array(3).fill(['x', 'y']))

so with repeat it would just be;

  • ['foo'].repeat(n)
  • ['x', 'y'].repeat(3)

For filling a new array with one value, Array(n).fill('foo') seems reasonable to me.

Are there use cases for filling with alternating values, as in ['x', 'y'].repeat(3)?

# J Decker (25 days ago)

On Sun, Mar 25, 2018 at 1:40 PM, Claude Pache <claude.pache at gmail.com>

wrote:

Le 25 mars 2018 à 20:27, Cyril Auburtin <cyril.auburtin at gmail.com> a écrit :

String and Array share a few methods.

I think repeat could exist for Array as well

At the moment are other more verbose ways to do so:

  • Array.from({length: n}, () => 'foo')
  • Array(n).fill('foo')
  • [].concat(...Array.from({length: 3}, () => ['x', 'y']))
  • [].concat(...Array(3).fill(['x', 'y']))

so with repeat it would just be;

  • ['foo'].repeat(n)
  • ['x', 'y'].repeat(3)

For filling a new array with one value, Array(n).fill('foo') seems reasonable to me.

Are there use cases for filling with alternating values, as in ['x', 'y'].repeat(3)?

maybe fill with incrementing number?

# Isiah Meadows (25 days ago)

I like this idea, and it has plenty of precedent in other languages (Python, Haskell, Clojure, etc.). It's more useful for arrays in my experience than even for strings.

Isiah Meadows me at isiahmeadows.com

Looking for web consulting? Or a new website? Send me an email and we can get started. www.isiahmeadows.com

# Isiah Meadows (25 days ago)

That could repeat an array, but it's not very good as a polyfill (it creates too many intermediate arrays). I'd expect a polyfill would be closer to this:

const ToInteger = x => (x = +x; x - x % 1)

Array.prototype.repeat = function repeat(count) {
    count = ToInteger(count)
    let o = Object(this)
    let length = ToInteger(o.length)
    let output = new Array(length * count)
    let i = 0
    while (i < count) {
        let j = 0
        while (j < length) output[i++] = o[j++]
    }
    return output
}

And while we're at it, could we also add a Array.prototype.set to mirror TypedArray.prototype.set? I could've used that several times already, and it's an easily vectorized operation.


Isiah Meadows me at isiahmeadows.com

Looking for web consulting? Or a new website? Send me an email and we can get started. www.isiahmeadows.com

# Isiah Meadows (25 days ago)

Edit: that while (i < count) should be while (i < end), where end = length * count. My bad.

Isiah Meadows me at isiahmeadows.com

Looking for web consulting? Or a new website? Send me an email and we can get started. www.isiahmeadows.com

# Isiah Meadows (25 days ago)

Edits:

  1. s/Haskell/Swift/g
  2. Most of my utility has been in things like random data.

Now that I take a second look at this, maybe it's better as just a utility function, not in the standard. (There isn't really anything this could provide that aren't possible otherwise, and it's not as broad of a use case as, say, Array.prototype.map or Math.random.)


Isiah Meadows me at isiahmeadows.com

Looking for web consulting? Or a new website? Send me an email and we can get started. www.isiahmeadows.com

# Jerry Schulteis (24 days ago)

Whatever the use cases might be, I like generators and spread for filling an array with values, e.g.:

[...repeat(3, 'x', 'y')]
On Sunday, March 25, 2018, 3:41:10 PM CDT, Claude Pache <claude.pache at gmail.com> wrote:  

[...] For filling a new array with one value, Array(n).fill('foo') seems reasonable to me. Are there use cases for filling with alternating values, as in ['x', 'y'].repeat(3)?

# Cyril Auburtin (24 days ago)

maybe fill with incrementing number?

Array.from({length: 6}, (_, i) => i)

Are there use cases for filling with alternating values, as in ['x', 'y'].repeat(3)?

Not so many, but for example when working with flat matrices, [0,0,255,1].repeat(len) for generating quickly a uniform imageData

But even with one item, I find [x].repeat(n) more explicit than the 2 other alternatiives

It's somewhat close to array comprehensions (that I don't really miss though)

2018-03-26 15:27 GMT+02:00 Jerry Schulteis <jdschulteis at yahoo.com>:

# Michael J. Ryan (23 days ago)

How about something like...

Array.prototype.fill = function(filler, times, flatten) { var ret = [].concat(this); var len = Number(times) || 0; var (var i=0; i<len; i++) { if (flatten && Array.isArray(filler)) { ret.push.apply(ret, filler); } else { ret.push(filler); } } return ret; }

[].fill(0, 3) // [0, 0, 0] [].fill(['a', 'b'], 2) // [['a', 'b'], ['a', 'b']] [].fill(['a', 'b'], 2, true) // ['a', 'b', 'a', 'b']

# Michael J. Ryan (23 days ago)

Or for that matter, similarly.... Array.fill(), which has the same signature, but an empty array as Array.prototype.fill.

# Jerry Schulteis (22 days ago)

First, Array.prototype.fill(value[, start[, end]]) already exists, so you need a new name (I'll provisionally use mjrFill). Second, Boolean arguments in an API are a pet peeve of mine, in js[].mjrFill(['a', 'b'], 2, true)it is not obvious what the third argument means.

Third, what was originally asked for was Array.prototype.repeat, analogous to String.prototype.repeat(count), which returns a new string consisting of the specified number of copies of the original, so:

['a', 'b'].repeat(2) // ['a', 'b', 'a', 'b']
[].mjrFill(arrayThatNeedsFlattening, n, true) // What does this do?
arrayThatNeedsFlattening.flatten().repeat(n); // Hard to misunderstand.
On Tuesday, March 27, 2018, 7:25:07 PM CDT, Michael J. Ryan <tracker1 at gmail.com> wrote:  

How about something like... Array.prototype.fill = function(filler, times, flatten) {  var ret = [].concat(this);  var len = Number(times) || 0;  var (var i=0; i<len; i++) {    if (flatten && Array.isArray(filler)) {      ret.push.apply(ret, filler);    } else {      ret.push(filler);    }  }  return ret;} [].fill(0, 3) // [0, 0, 0][].fill(['a', 'b'], 2) // [['a', 'b'], ['a', 'b']][].fill(['a', 'b'], 2, true) // ['a', 'b', 'a', 'b']