Array.prototype.repeat

# Cyril Auburtin (6 years 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 (6 years 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 (6 years 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 (6 years 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 (6 years 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 (6 years 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 (6 years 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 (6 years 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 (6 years 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 (6 years 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 (6 years 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 (6 years ago)

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

# Jerry Schulteis (6 years 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']

# Cyril Auburtin (6 years ago)

pro: I think it's quite frequent to need Array.from({length: .. }, () => ...)
con: you can't generate dynamic data (like an array of random values)

I think in the end this Array.prototype.repeat is not a good idea, but there should be something easier/less verbose than Array.from({length: ..}, (_, i) => i)

maybe Array.repeat(len, i => ..) ?

Le mer. 28 mars 2018 à 17:10, Jerry Schulteis <jdschulteis at yahoo.com> a écrit :

# Jordan Harband (6 years ago)

perhaps array.build