最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How do I easily combine elements from two arrays in Javascript, alternating elements? - Stack Overflow

programmeradmin1浏览0评论

I have two arrays in JavaScript, of potentially different lengths:

var x = ['a', 'b', 'c'];
var y = ['g', 'h', 'i', 'j'];

I'd like to bine them into one array:

var z = ['a', 'g', 'b', 'h', 'c', 'i', 'j'];

How can I do that in JavaScript?

I have two arrays in JavaScript, of potentially different lengths:

var x = ['a', 'b', 'c'];
var y = ['g', 'h', 'i', 'j'];

I'd like to bine them into one array:

var z = ['a', 'g', 'b', 'h', 'c', 'i', 'j'];

How can I do that in JavaScript?

Share Improve this question asked Nov 2, 2016 at 9:52 Andrew FerrierAndrew Ferrier 17.8k14 gold badges54 silver badges78 bronze badges
Add a ment  | 

7 Answers 7

Reset to default 7

I see you answered your question at the same time as asking it. That's fine, but it's now clear that you were looking for a solution that leverages a library (eg, lodash) and not necessarily one that teaches you how to build such a procedure. In retrospect, I would've answered this differently, but nevertheless I think you can learn something from this answer.


I would remend calling this something other than zip just because zip is used as name for a procedure that does something quite different from what you're looking for.

Here's a simple recursive definition of interleave -

const interleave = ([ x, ...xs ], ys = []) =>
  x === undefined
    ? ys                             // base: no x
    : [ x, ...interleave (ys, xs) ]  // inductive: some x

const xs = [ 'a', 'b', 'c' ]
  
const ys = [ 'g', 'h', 'i', 'j' ]

console .log (interleave (xs, ys))
// [ a, g, b, h, c, i, j ]

And another variation that supports any number of input arrays -

const interleave = ([ x, ...xs ], ...rest) =>
  x === undefined
    ? rest.length === 0
      ? []                                // base: no x, no rest
      : interleave (...rest)              // inductive: no x, some rest
    : [ x, ...interleave (...rest, xs) ]  // inductive: some x, some rest

const ws = [ '0', '1', '2', '3' ]

const xs = [ 'a', 'b', 'c' ]

const ys = [ 'd', 'e', 'f' ]

const zs = [ 'g', 'h', 'i', 'j' ]

console .log (interleave (ws, xs, ys, zs))
// [ 0, a, d, g, 1, b, e, h, 2, c, f, i, 3, j ]

tl;dr: z = _.flatten(_.zip(x, y)).filter(element => element), as long as you don't care about null elements in the original arrays.


Some of the libraries providing functional tools, such as Lodash, provide enough mechanics to easily do this. For example, you can do this:

var z1 = _.zip(x, y);
// z1 is now [["a","g"],["b","h"],["c","i"],[null,"j"]]

var z2 = _.flatten(z1);
// z2 is now ["a","g","b","h","c","i",null,"j"]

var z3 = z2.filter(element => element)
// z3 is now ["a","g","b","h","c","i","j"]

Note that this will only work if the original arrays do not contain any null elements, as they are filtered out by the last step.

A simple implementation that will stitch the arrays:

function stitch(x, y) {
  var arr = [];
  var length = Math.max(x.length, y.length);
  for(var i = 0; i < length; i++) {
    i < x.length && arr.push(x[i]);
    i < y.length && arr.push(y[i]);
  }
  
  return arr;
}

var x = ['a', 'b', 'c'];
var y = ['g', 'h', 'i', 'j'];

console.log(stitch(x, y));

This is the functional way to address the problem:

var x = ['a', 'b', 'c'];
var y = ['g', 'h', 'i', 'j'];

function stitch(x,y) {

var a = x.length > y.length ? x : y;
var b = x.length > y.length ? y : x;

var c = a.map(function (e, i) {
    return b.length<i ? [e, b[i]] : [];
});

return [].concat.apply([],c)
}

Here's a very simple recursive solution:

const interlace = (xxs, ys) => {
    if (xxs.length === 0) return ys;
    const  [x, ...xs] = xxs;
    return [x, ...interlace(ys, xs)];
};

const xs = ['a', 'b', 'c'];
const ys = ['g', 'h', 'i', 'j'];

console.log(JSON.stringify(interlace(xs, ys)));

In addition, you can easily generalize this algorithm to an arbitrary number of arrays:

const interlace = (...xss) => xss.length > 0 ? interleave(...xss) : [];

const interleave = (xxs, ...yss) => {
    if (xxs.length === 0) return interlace(...yss);
    const  [x, ...xs] = xxs;
    return [x, ...interleave(...yss, xs)];
};

const xs = ['a', 'b', 'c'];
const ys = ['g', 'h', 'i', 'j'];
const zs = ['d', 'e', 'f'];

console.log(JSON.stringify(interlace()));
console.log(JSON.stringify(interlace(xs)));
console.log(JSON.stringify(interlace(xs, ys)));
console.log(JSON.stringify(interlace(xs, ys, zs)));

Hope that helps.

This can be done in regular Javascript. No need for fancy tricks:

function splicer(array, element, index) {
    array.splice(index * 2, 0, element);
    return array;
}

function weave(array1, array2) {
    return array1.reduce(splicer, array2.slice());
}

var x = ['a', 'b', 'c'];
var y = ['g', 'h', 'i', 'j'];

var z = weave(x, y);

console.log(z);

var x = ['a', 'b', 'c'];
var y = ['g', 'h', 'i', 'j'];

var z=[];
if(y.length>=x.length){
  for(var i=0;i<x.length;i++){
    z.push(x[i]);
    z.push(y[i]);
  }
  while(i<y.length)
    z.push(y[i++]);
  
}else{
  for(var i=0;i<y.length;i++){
    z.push(x[i]);
    z.push(y[i]);
  }
  while(i<x.length)
    z.push(x[i++]);  
}

window.alert(JSON.stringify(z)); // print ["a","g","b","h","c","i","j"]

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论