Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combine two arrays in a "zipping" fashion - JavaScript

So, I've been thinking of just some little practice things that I could do with arrays in JavaScript. I came across the idea of combining two arrays in a "zipping" fashion (arrayA[0], arrayB[0], arrayA[1], arrayB[1]...) and so on and so forth. Anything left over in a potential longer array would be tacked onto the end.

I've searched stackoverflow - reason I'm asking is I'm currently in introductory programming courses, so we don't really know a whole lot of "things" we can do with JavaScript. Would like to see a solution with "simple" methods if possible!

I've currently got the alternate fashion going, but I can't seem to get the last part of tacking the remaining parts of the array to the very end.

function alternatingMerge(array1, array2)
//this function will merge two different arrays in an alternating fashion
//i.e = array1[0], array2[0], array1[1], array2[1], array1[2], array2[2], ... , etc
{
    var mergedArray;
    var i; // while loop counter
    var j; // 
    var k; // 
    var arrayLengths;

    arrayLengths = array1.length + array2.length;
    i = 0; // 
    j = 0; // ARRAY1 COUNTER
    k = 0; // ARRAY2 COUNTER
    mergedArray = new Array(arrayLengths);
    //window.alert(mergedArray);

    while (i < arrayLengths)
    {
        if (i%2 === 0)
        {
            mergedArray[i] = array2[j];
            j = j + 1;
        }
        else
        {
            mergedArray[i] = array1[k];
            k = k + 1;
        }
        i = i + 1;
    }
    return mergedArray;
}

I feel like it's simple stuff but some help would be appreciated!

like image 998
Chad Avatar asked Dec 05 '22 16:12

Chad


2 Answers

Here is a small but effective weaving function for two arrays of any size using ES6 (modern browsers):

const w = (a, b) => a.length ? [a[0], ...w(b, a.slice(1))] : b;

const array1 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
const array2 = ['A', 'B', 'C', 'D', 'E'];

console.log(JSON.stringify(w(array1, array2)));

Explanation:

The variable w is set to this short recursive function:

(a, b) => a.length ? [a[0], ...w(b, a.slice(1))] : b

I'll explain it piece by piece since there's no room for comments.

(a, b) => - For two input arrays, a and b.

a.length - Check if the first array is not empty.

? [___] - If it is not empty, return an array.

a[0], - Make the first item in this array the same first item from the first array.

...w(b, a.slice(1)) - Fill the rest of the array with the results of this same function using array b for the first parameter and everything but the first item of array a for the second parameter.

: b - Otherwise, if the first array is empty, return array b.

What it ends up doing is switching between the first and second arrays, removing the first item from that array and passing it back recursively to the result array. It does this until one of the arrays has no items left, at which point the rest of the other array is returned and added to the end of the result.


With a few adjustments, it can rotate through any number of arrays. This version runs basically the same way, except the first array gets a default value to handle no arguments being fed in, and the second parameter handles multiple arrays instead of one. Also, before checking the length of array a, it counts the arrays in b to see if there are any arrays left to rotate through. If there aren't any, array a is returned. If there are arrays left, but a is empty, the results of the recursive function are returned using the remaining arrays as its parameters.

const w = (a = [], ...b) => 
    b.length ? a.length ? [a[0], ...w(...b, a.slice(1))] : w(...b) : a;

const array1 = [1, 2];
const array2 = 'โ™ฆโ™กโ™ฃโ™คโ™ฅโ™ข';
const array3 = ['A', 'B', 'C'];
const array4 = ['๐Ÿ˜Š', '๐Ÿ˜”', '๐Ÿ˜ '];
const array5 = [null, NaN, undefined];

const stringify = (o) => JSON.stringify(o, (k, v) => v === undefined ? '__undefined__' : v !== v ? '__NaN__' : v).replace(/"__undefined__"/g, 'undefined').replace(/"__NaN__"/g, 'NaN');

console.log(stringify(w()));
console.log(stringify(w(array1)));
console.log(stringify(w(array1, array2)));
console.log(stringify(w(array1, array2, array3)));
console.log(stringify(w(array1, array2, array3, array4)));
console.log(stringify(w(array1, array2, array3, array4, array5)));

The stringify function is something I added to correct for JSON.stringify converting NaN and undefined into null. It does not effect the way the weaving function works.

like image 77
omikes Avatar answered Dec 29 '22 13:12

omikes


How about this:

function mergeAlternating(array1, array2) {
    var mergedArray = [];

    for (var i = 0, len = Math.max(array1.length, array2.length); i < len; i++) {
        if (i < array1.length) {
            mergedArray.push(array1[i]);
        }
        if (i < array2.length) {
            mergedArray.push(array2[i]);
        }
    }
    return mergedArray;
}
like image 41
jfriend00 Avatar answered Dec 29 '22 13:12

jfriend00