如何在Javascript,交替元素中轻松组合来自两个数组的元素?

时间:2016-11-02 09:53:00

标签: javascript arrays functional-programming

我在JavaScript中有两个数组,可能有不同的长度:

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

我想将它们组合成一个数组:

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

我如何在JavaScript中执行此操作?

7 个答案:

答案 0 :(得分:5)

我看到你在问这个问题的同时回答了你的问题。这很好,但现在很清楚,你正在寻找一个利用库(例如,lodash)的解决方案,而不一定是教你如何构建这样一个程序的解决方案。回想起来,我会以不同的方式回答这个问题,但我认为你可以从这个答案中学到一些东西。

我建议只调用zip之外的其他内容,因为zip用作执行与您正在寻找的内容完全不同的过程的名称。

这是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 ]

另一种支持任意数量输入数组的变体 -

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 ]

答案 1 :(得分:3)

一个简单的实现,它将拼接数组:

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));

答案 2 :(得分:2)

tl; dr z = _.flatten(_.zip(x, y)).filter(element => element),只要您不关心原始数组中的 null 元素。

一些提供功能工具的库(例如Lodash)提供了足够的机制来轻松完成此操作。例如,您可以这样做:

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"]

请注意,这仅在原始数组不包含任何null元素时才有效,因为它们在最后一步被过滤掉。

答案 3 :(得分:1)

这是解决问题的有效方法:

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)
}

答案 4 :(得分:1)

这是一个非常简单的递归解决方案:

&#13;
&#13;
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)));
&#13;
&#13;
&#13;

此外,您可以轻松地将此算法推广到任意数量的数组:

&#13;
&#13;
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)));
&#13;
&#13;
&#13;

希望有所帮助。

答案 5 :(得分:0)

这可以使用常规Javascript完成。无需花哨的技巧:

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);

答案 6 :(得分:-1)

&#13;
&#13;
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"]
&#13;
&#13;
&#13;