0

Given arrays arr1, arr2, and newArr (for instance):

var arr1 = ["a1", "a2", "a3", "a4", "a5"]
var arr2 = ["b1", "b2", "b3", "b4", "b5"]
var newArr = ["a1", "a2", "a3", "b1", "b2", "b3", "a4", "a5", "b4", "b5"]

I am trying to combine two arrays (arr1 and arr2) into one array (newArr), in such a way that newArr grabs the first (up to) three elements from arr1, then the first (up to) three from arr2, then the next (up to) three from arr1, etc.

I'd initially approached this by iterating through every element of arr1 and checking to see if the index is divisible by three (for (var i = 0) ... if (i + 1 % 3 === 0)), but now I'm thinking that this approach is untenable when arr1.length % 3 !== 0.

Also, is there a name for this kind of merge procedure?

alex
  • 6,818
  • 9
  • 52
  • 103
  • Are your arrays the same length ? Can you be clearer by using really different input arrays? – Denys Séguret Apr 08 '16 at 14:35
  • Yes - my arrays are the same length. I'll edit my snippet to distinguish the arrays better. – alex Apr 08 '16 at 14:40
  • 1
    _is there a name for this kind of merge procedure_ well, the division is sometimes called [chunking](http://stackoverflow.com/questions/8495687/split-array-into-chunks); using that question and `concat`ting the results should get you where you want to go. – Evan Davis Apr 08 '16 at 15:01

3 Answers3

2

How about...

var arr1 = ["a1", "a2", "a3", "a4", "a5"]
var arr2 = ["b1", "b2", "b3", "b4", "b5"]
newArr = []
t1 = t2 = temp = []

while(arr1.length) {
  t1 = arr1.splice(0,3)
  t2 = arr2.splice(0,3)
  temp = t1.concat(t2)
  newArr = newArr.concat(temp)
}
console.log(newArr)
Michael Oakley
  • 383
  • 3
  • 5
  • This approach is the most similar to what I ended up going with - keeps it simple. Thanks! – alex Apr 09 '16 at 00:21
1

Excuse me, do you have a minute to talk about our Lord and Savior, recursion?

/**
 * @param {number[]} arr1
 * @param {number[]} arr2
 */
function threeMerge(arr1, arr2) {

    /**
    * @param {number[]} arr1
    * @param {number[]} arr2
    * @param {number[]} currentArr
    */
    var threeMergeRecursive = function(arr1, arr2, currentArr) {
        if(arr1.length < 3 || arr2.length < 3){
            return currentArr.concat(arr1, arr2);
    } else if (arr2.length < 3) {
        var resultArr = currentArr.concat(
            arr1.slice(0, 3),
            arr2
        );

        return threeMergeRecursive(
            arr1.slice(0, 3),
            [],
            resultArr
        );
    } else {
            var resultArr = currentArr.concat(
                arr1.slice(0, 3),
                arr1.slice(0, 3)
                );

            return threeMergeRecursive(
                arr1.slice(3),
                arr2.slice(3),
                resultArr);
        }
    };

    return(threeMergeRecursive(arr1, arr2, []));
};
DogPawHat
  • 437
  • 3
  • 9
1

Basic solution is to loop with two indexes simultaneously. Here is solution

var arr1 = ["a1", "a2", "a3", "a4", "a5"],
    arr2 = ["b1", "b2", "b3", "b4", "b5"],
    newArr = [];

for (let a=0, b=0; a<arr1.length || b<arr2.length; ) {
  if (a==b) {
    newArr.push(...arr1.slice(a,a+=3)) }
  else {
    newArr.push(...arr2.slice(b,b+=3)) }
}

Please notice sample code use let and array unboxing ES6 features.

Nick Rassadin
  • 860
  • 7
  • 7