2

Is there anyway to merge arrays in javascript by ordering by index/position. I'm try to accomplish this and haven't been able to find any examples of this.

var array1 = [1,2,3,4] var array2 = [a,b,c,d] var array3 = [!,@,#,$]

var merged array = [1,a,!,2,b,@,3,c,#,4,d,$]

I know you can use concat() to put one after the other.

2
  • 1
    Note that you have to put your array elements in quotes if you want them to be strings. Otherwise they refer to variables, and things like ! aren't legal variable names. Commented May 26, 2011 at 20:01
  • Sorry for the sloppy syntax, this was mostly just to illustrate my end goal. Commented May 26, 2011 at 20:14

9 Answers 9

3

As long as the arrays are all the same length you could just do:

var mergedArray = [];
for (var i = 0, il = array1.length; i < il; i++) {
  mergedArray.push(array1[i]);
  mergedArray.push(array2[i]);
  mergedArray.push(array3[i]);
}

EDIT: For arrays of varying lengths you could do:

var mergedArray = [];
for (var i = 0, il = Math.max(array1.length, array2.length, array3.length); 
     i < il; i++) {
  if (array1[i]) { mergedArray.push(array1[i]); }
  if (array2[i]) { mergedArray.push(array2[i]); }
  if (array3[i]) { mergedArray.push(array3[i]); }
}
Sign up to request clarification or add additional context in comments.

7 Comments

You can do this with only one call to push
The arrays will be dynamic, and may not always have the same length. How would I get the merged array in that situation? Thank you for the help!
See my answer for arrays of any length.
Edit: Updated for arrays of any length.
The only problem with this solution is that the names/amount of the arrays are hard coded. If you were receiving the names of the arrays or possibly a varying number of arrays from a server, this code would need to be modified.
|
2

This should work for arrays of ANY length:

var mergeArrays = function () {
    var arr = [],
        args = arr.slice.call(arguments),
        length = 0;

    for (var i = 0, len = args.length; i < len; i++) {
        length = args[i].length > length ? args[i].length : length;
    }

    for (i = 0; i < length; i++) {
        for (var j = 0; j < len; j++) {
            var value = args[j][i];

            if (value) {
                arr.push(value);
            }
        }
    }

    return arr;
};

Example:

var array1 = [1,2,3,4];
var array2 = ['a','b','c','d','e','f','g','h','i','j','k','l'];
var array3 = ['!','@','#','$','%','^','&','*','('];

mergeArrays(array1, array2, array3);
// outputs: [1, "a", "!", 2, "b", "@", 3, "c", "#", 4, "d", "$", "e", "%", "f", "^", "g", "&", "h", "*", "i", "(", "j", "k", "l"]

This would work also (a little more terse syntax):

var mergeArrays = function () {
    var arr = [],
        args = arr.slice.call(arguments),
        length = Math.max.apply(null, args.map(function (a) { return a.length; }));

    for (i = 0; i < length; i++) {
        for (var j = 0, len = args.length; j < len; j++) {
            var value = args[j][i];

            if (value) {
                arr.push(value);
            }
        }
    }

    return arr;
};

1 Comment

Awesome, this works perfectly and is actually a better solution moving forward. Thank you for the help!
2

For arrays that are all the same size, where you pass one or more arrays as parameters to merge:

function merge()
{
    var result = [];
    for (var i=0; i<arguments[0].length; i++)
    {
        for (var j=0; j<arguments.length; j++)
        {
            result.push(arguments[j][i]);
        }
    }
    return result;
}

var array1 = ['1','2','3','4'];
var array2 = ['a','b','c','d'];
var array3 = ['!','@','#','$'];
var merged = merge(array1, array2, array3);

Comments

0

Nothing built in, but it wouldn't be hard to manage:

var maxLength = Math.max(array1.length, array2.length, array3.length),
    output = [];

for (var i = 0; i < maxLength; i++) {
    if (array1[i] != undefined) output.push(array1[i]);
    if (array2[i] != undefined) output.push(array2[i]);
    if (array3[i] != undefined) output.push(array3[i]);
}

Comments

0

try this...

var masterList = new Array();
var array1 = [1,2,3,4];
var array2 = [a,b,c,d];
var array3 = [!,@,#,$];
for(i = 0; i < array1.length; i++) {
    masterList.push(array1[i]);
    masterList.push(array2[i]);
    masterList.push(array3[i]);
}

Comments

0

It looks like you want to "zip" some number of same-length arrays into a single array:

var zip = function() {
  var numArrays=arguments.length
    , len=arguments[0].length
    , arr=[], i, j;
  for (i=0; i<len; i++) {
    for (j=0; j<numArrays; j++) {
      arr.push(arguments[j][i]);
    }
  }
  return arr;
};

zip([1,2], ['a', 'b']); // => [1, 'a', 2, 'b']
zip([1,2,3], ['a','b','c'], ['!','@','#']); // => [1,'a','@',...,3,'c','#']

If the input arrays could be of different length then you've got to figure out how to deal with that case...

Comments

0

Yes, there is some way to do that. Just:

  • loop through the larger array,
  • until at the currently processed position both arrays have elements, assign them one-by-one to the new array,
  • after the shorter array ends, assign only elements from the longer array,

The resulting array will have the elements ordered by the index from the original arrays. From your decision depends, position in which one of these arrays will have higher priority.

Comments

0

This works for any number of array and with arrays of any length.

function myMerge() {
  var result = [],
      maxLength = 0;
  for (var i = 0; i < arguments.length; i++) {
    if (arguments[i].length > maxLength) { maxLength = arguments[i].length; }
  }
  for (var i = 0; i < maxLength; i++) {
    for (var j = 0; j < arguments.length; j++) {
      if (arguments[j].length > i) {
        result.push(arguments[j][i]);
      }
    }
  }
  return result;
}

5 Comments

You shouldn't use for...in on arrays.
1. It will enumerate additions to the array prototype, 2. The order of for..in is undefined.
If anyone extends the Array prototype (adding methods to Array instances), then they show up in the for..in loop. For instance, if you add an Array.prototype.each method (like jQuery does), your loop will contain the array indices (like 0...n) and 'each'.
jQuery does not extend the prototype of anything as far as I know.
@Shurdoof: I didn't know that. I took out my for...in statements thx
0

Eli beat me to the punch up there.

var posConcat = function() {
    var arrays = Array.prototype.slice.call(arguments, 0),
        newArray = [];

    while(arrays.some(notEmpty)) {
        for(var i = 0; i < arrays.length; i++) {
            if(arguments[i].length > 0)
                newArray.push(arguments[i].shift());
        }
    }

    return newArray;
},

notEmpty = function() { return arguments[0].length > 0; };

Usage:

var orderedArray = posConcat(array1,array2,array3);

Sample: http://jsfiddle.net/HH9SR/

Comments

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.