18

Let's say I'm given an array. The length of this array is 3, and has 3 elements:

var array = ['1','2','3'];

Eventually I will need to check if this array is equal to an array with the same elements, but just twice now. My new array is:

var newArray = ['1','2','3','1','2','3'];

I know I can use array.splice() to duplicate an array, but how can I duplicate it an unknown amount of times? Basically what I want is something that would have the effect of

var dupeArray = array*2;
6
  • Do you want a function to compare two arrays or generate a new array from a given array? Commented May 14, 2015 at 3:50
  • var arr=[1,2,3]; arr.map([].valueOf.bind(arr)) Commented May 14, 2015 at 3:50
  • @Trott I have a function to compare the elements of two arrays. What I guess i'm looking for is a function to generate a new array an unknown amount of times from the given array. Commented May 14, 2015 at 3:51
  • 2
    At the point at which you are duplicating, you will know how many times you want to "duplicate" it, correct? Why can't you just use concat / splice / whatever multiple times? Commented May 14, 2015 at 3:51
  • 1
    Eventually I will need to check if this array is equal to an array with the same elements, but just twice now. Would this happen to be the X of your XY problem? In other words, is this your end goal? Commented May 14, 2015 at 3:52

10 Answers 10

17
const duplicateArr = (arr, times) =>
    Array(times)
        .fill([...arr])
        .reduce((a, b) => a.concat(b));

This should work. It creates a new array with a size of how many times you want to duplicate it. It fills it with copies of the array. Then it uses reduce to join all the arrays into a single array.

Sign up to request clarification or add additional context in comments.

3 Comments

We now have .join() to replace the reduce
@kano .join() outputs a string, did you mean flat()?
Yes I did, thanks! Silly-brain-moment... * facepalms *
6

The simplest solution is often the best one:

function replicate(arr, times) {
     var al = arr.length,
         rl = al*times,
         res = new Array(rl);
     for (var i=0; i<rl; i++)
         res[i] = arr[i % al];
     return res;
}

(or use nested loops such as @UsamaNorman).

However, if you want to be clever, you also can repeatedly concat the array to itself:

function replicate(arr, times) {
    for (var parts = []; times > 0; times >>= 1) {
        if (times & 1)
            parts.push(arr);
        arr = arr.concat(arr);
    }
    return Array.prototype.concat.apply([], parts);
}

1 Comment

It should probably be res = new Array(rl); though no? And i < rl in the for loop. Regardless I upvoted.
3

Basic but worked for me.

var num = 2;

while(num>0){
array = array.concat(array);
num--}

Comments

2

Here's a fairly concise, non-recursive way of replicating an array an arbitrary number of times:

function replicateArray(array, n) {
  // Create an array of size "n" with undefined values
  var arrays = Array.apply(null, new Array(n)); 

  // Replace each "undefined" with our array, resulting in an array of n copies of our array
  arrays = arrays.map(function() { return array });

  // Flatten our array of arrays
  return [].concat.apply([], arrays);
}

console.log(replicateArray([1,2,3],4)); // output: [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]

What's going on?

The first two lines use apply and map to create an array of "n" copies of your array.

The last line uses apply to flatten our recently generated array of arrays.

Seriously though, what's going on?

If you haven't used apply or map, the code might be confusing.

The first piece of magic sauce here is the use of apply() which makes it possible to either pass an array to a function as though it were a parameter list.

Apply uses three pieces of information: x.apply(y,z)

  • x is the function being called
  • y is the object that the function is being called on (if null, it uses global)
  • z is the parameter list

Put in terms of code, it translates to: y.x(z[0], z[1], z[2],...)

For example

var arrays = Array.apply(null, new Array(n));

is the same as writing

var arrays = Array(undefined,undefined,undefined,... /*Repeat N Times*/);

The second piece of magic is the use of map() which calls a function for each element of an array and creates a list of return values.

This uses two pieces of information: x.map(y)

  • x is an array
  • y is a function to be invoked on each element of the array

For example

var returnArray = [1,2,3].map(function(x) {return x + 1;});

would create the array [2,3,4]

In our case we passed in a function which always returns a static value (the array we want to duplicate) which means the result of this map is a list of n copies of our array.

3 Comments

Tricky code, but it sure isn't easy to follow what it does. I, for one, prefer code that anybody can immediately see what it does. There are no points for brevity in my book and there are points for clarity, ease of understanding.
Fair enough! I was just combining answers from SO to show how you could look up subquestions to build a compound answer. I'll break it out a little more.
Updated plus a detailed explanation. Alas, it may be that apply and map are just always going to be advanced concepts that is a little hard to expect everyone to be able to get at first glance.
1

You can do:

var array = ['1','2','3'];


function nplicate(times, array){
      //Times = 2, then concat 1 time to duplicate. Times = 3, then concat 2 times for duplicate. Etc.
     times = times -1;
     var result = array;

    while(times > 0){
        result = result.concat(array);
        times--;
    }

    return result;
}

console.log(nplicate(2,array));

You concat the same array n times.

Use concat function and some logic: http://www.w3schools.com/jsref/jsref_concat_array.asp

1 Comment

Thanks, now its ok? I edited it. Sorry for the mistake. But i understand to make a function to concatenate a array n times.
1

Keep it short and sweet

function repeat(a, n, r) {
    return !n ? r : repeat(a, --n, (r||[]).concat(a));
}

console.log(repeat([1,2,3], 4)); // [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]

http://jsfiddle.net/fLo3uubk/

2 Comments

Much shorter and sweeter: function replicate(a, n) { return !n ? [] : repeat(a, n-1).concat(a); }
@Bergi Great! Just don't forget to replace "repeat" with "replicate" ;-)
1

if you are inside a loop you can verify the current loop index with the array length and then multiply it's content.

let arr = [1, 2, 3];

if(currentIndex > arr.length){ 
  //if your using a loop, make sure to keep arr at a level that it won't reset each loop

  arr.push(...arr);

}

Full Example: https://jsfiddle.net/5k28yq0L/

Comments

1

You can do this quite simply with fill and flat:

const arr = [1, 2, 3, 4], times = 3;
const result = Array(times).fill(arr).flat();
console.log(result);

Often it is a bad idea to pass an object as argument to fill, as the array gets filled with the same object (array) reference. But here flat creates a new array from that (repeated) input, so there is no issue. Of course, if the input has nested objects, no deep copy is taken (as none of the answers here do).

Comments

0

I think you will have to write your own function, try this:

function dupArray(var n,var arr){
var newArr=[];
for(var j=0;j<n;j++)
    for(var i=0;i<arr.length;i++){
        newArr.push(arr[i]);
    }
return newArr;
}

4 Comments

The use will be like this: myArr = dupArray(5,previousArr);
There are better ways to do this than nested for loops! Also you may want to edit your answer to include the usage, rather than writing it as a comment.
@slifty: Better ways such as?
0

A rather crude solution for checking that it duplicates... You could check for a variation of the length using modulus:

Then if it might be, loop over the contents and compare each value until done. If at any point it doesn't match before ending, then it either didn't repeat or stopped repeating before the end.

if (array2.length % array1.length == 0){
    // It might be a dupe
    for (var i in array2){
        if (i != array1[array2.length % indexOf(i)]) { // Not Repeating }
    }
}

1 Comment

When you use the "for var i in array2" syntax you're looping through the indices of array2. so this answer is really messed up. Perhaps using Array.prototype.forEach would be more elegant here. Using modulo is a good idea to solve this problem so I like that part of your answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.