5

I'm trying to combine two arrays and most of the answers relate to adding the second array to the end of the first. I need to merge index to index.

Here's example code:

let arr1 = ['golf', 'hockey', 'tennis'];
let arr2 = ['player1', 'player2', 'player3'];

Array.prototype.zip = function (arr) {
  return this.map(function (e, i) {
    return [ e, arr[i]];
  })
};
const arr3 = arr1.zip(arr2);
console.log(arr3);

The result should be:

['golf', 'player1', 'hockey', 'player2', 'tennis', 'player3']

The above code looks like it should work but doesn't. If it can be fixed, or exchanged for better that would be great.....

2
  • 2
    Please don't mutate the built-in objects. Commented Apr 19, 2018 at 3:44
  • Okay, just to add - the end result I need is this ['golf', 'player1', 'hockey', 'player2', 'tennis', 'player3'] Commented Apr 19, 2018 at 3:48

4 Answers 4

3

You can use .reduce() to zip both arrays:

let arr1 = ['golf', 'hockey', 'tennis'],
    arr2 = ['player1', 'player2', 'player3'];

let zip = (a1, a2) => a1.reduce((a, c, i) => (a.push(c, a2[i]), a), []);

console.log(zip(arr1, arr2));

Docs:

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

1 Comment

I realised that I gave the wrong example object which massively affects the result. So i'm calling this answer correct because it's the first answer given that works according to the incorrect info I gave. I wrote a new question on stackoverflow link here - stackoverflow.com/questions/49921853/…
0

.map maps an array to another array one-to-one: if you have 3 elements in the original array, .map can only ever produce another array that has 3 elements. If you can't use concat, use .reduce instead of .map, that way you can push multiple elements in a single iteration:

const arr1 = ['golf', 'hockey', 'tennis'];
const arr2 = ['player1', 'player2', 'player3']

Array.prototype.zip = function (otherArr) {
  return this.reduce((accum, item, i) => {
    accum.push(item);
    accum.push(otherArr[i]);
    return accum;
  }, []);
};
const arr3 = arr1.zip(arr2)
console.log(arr3)

Of course, it would be much better not to change the built-in Array object. You could easily avoid that by using a standalone function instead:

const arr1 = ['golf', 'hockey', 'tennis'];
const arr2 = ['player1', 'player2', 'player3']

function zip(arr1, arr2) {
  return arr1.reduce((accum, item, i) => {
    accum.push(item);
    accum.push(arr2[i]);
    return accum;
  }, []);
};
const arr3 = zip(arr1, arr2);
console.log(arr3);

Comments

0

A simple fix: Just flatten what you have now with a simple reduce():

let arr1 = ['golf', 'hockey', 'tennis'];
let arr2 = ['player1', 'player2', 'player3']

Array.prototype.zip = function (arr) {
      return this.map(function (e, i) {
          return [ e, arr[i]]
      }).reduce((a,b)=>a.concat(b)); // blink and you miss the change...
    };
const arr3 = arr1.zip(arr2)
console.log(arr3)

This approach preserves what you have and doesn't add a lot of complexity like extra method calls, temp arrays, etc; that's the beauty of the functional approach: you're one chain link away from what you need. I would also convert it to a stand-along method instead of modding the prototype, but that's aside the point...

Comments

0

You can use temp array instead of direct input method.

let arr1 = ['golf', 'hockey', 'tennis'];
let arr2 = ['player1', 'player2', 'player3']

Array.prototype.zip = function (arr) {
    this.map(function (e, i) { this.splice(i*2+1, 0, arr[i]); }, this )
};
const arr3 = arr1.zip(arr2)
console.log(arr3)

1 Comment

Oh, it looks more clean. Thanks.

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.