合并两个数组,使值交替出现

24

我正在寻找一种jQuery方法,以便合并两个数组,使它们的值交替出现:

var array1 = [1,2,3,4,5];
var array2 = ['a', 'b', 'c', 'd', 'e'];

我想要的结果是:

var arrayCombined = [1, 'a', 2, 'b', 3, 'c', 4, 'd', 5, 'e'];

请注意,我知道用JS很容易做到这一点,但我想要一个可以实现这一点的jQuery方法。


5
没有jQuery方法,为什么需要用jQuery来做这件事情呢?! - Prisoner
5
为什么?就像你所说的,在纯JavaScript中进行这个操作是微不足道的。 - Matt Burland
3
为什么?这与 DOM 或 jQuery 的特定用途无关。 - pimvdb
11
是否必须有一种jQuery的方法来完成所有事情? - deceze
1
如果用JavaScript可以轻松解决,就使用JavaScript。使用适合的工具来完成任务。 - Jay Blanchard
显示剩余5条评论
7个回答

37
你可以使用map方法:

var array1 = [1, 2, 3, 4, 5];
var array2 = ['a', 'b', 'c', 'd', 'e'];

var arrayCombined = $.map(array1, function(v, i) {
  return [v, array2[i]];
});

console.log(arrayCombined);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

示例:http://jsfiddle.net/Guffa/hmUy6/


11
var arrayCombined = array1.map(function(v,i) { return [v, array2[i]]; }).reduce(function(a,b) { return a.concat(b); }); 这行代码是用于在纯ES5 JavaScript中将两个数组按相同索引位置合并成一个新的数组。它首先使用map方法将两个数组中对应索引位置上的元素放到一个新数组中,然后使用reduce方法将新数组中的所有元素连接在一起。最后,使用变量arrayCombined存储合并后的数组。 - jAndy
3
谢谢您实际回答问题,而不是像预料的那样大惊小怪地说这可以在没有 jQuery 的情况下完成。 - Undistraction
1
如果在jsfiddle中添加一个链接回到这里,我会给你点赞的。我是通过jsfiddle找到这个链接的。 - Neil
我已经将@jAndy的代码泛化以支持合并数组的数组。这是用ES6编写的:combined = arraysArray[0].map((v, i) => arraysArray.reduce((a, b) => a.concat(b[i]), [])).reduce((a, b) => a.concat(b), []); - Gal Talmor
1
数组的数组版本,类似于@GalTalmor的代码:combined = arraysArray.reduce((t, u, v, w) => u.reduce((x, y, z) => (x[z * w.length + v] = y, x), t), []); 它非常快!http://jsben.ch/2ZIGk - omikes
或者只针对2个数组:var arrayCombined = array1.reduce((x, y, z) => (x.splice(z * 2, 0, y), x), array2.slice()); - omikes

18

如果你确实需要使用jQuery,那么你可以利用他们有缺陷的$.map实现。

var result = $.map(array1, function(v, i) {
                                return [v, array2[i]];
                           });

jQuery的$.map会将返回的数组压平,从而给你想要的结果。

演示: http://jsfiddle.net/8rn2w/


纯JS解决方案:

var result = array1.reduce(function(arr, v, i) {
                              return arr.concat(v, array2[i]); 
                           }, []);

演示: http://jsfiddle.net/8rn2w/1/


3
已有文档记录,因此这不是一个错误。 - John Dvorak
2
@JanDvorak:是的,但在我看来,它仍然有问题。 - I Hate Lazy
2
@JanDvorak:你比我更有风度。 :) - I Hate Lazy

7

使用 Array.prototype.flat()Array.prototype.map() 的另一种解决方案。

var array1 = [1, 2, 3, 4, 5];
var array2 = ['a', 'b', 'c', 'd', 'e'];

var result = array1.map(
  (element, index) => [element, array2[index]]
).flat();

console.log(result);


注意:Array.prototype.flat() 需要 Node.js 11.0.0 或更高版本。 - jarmod
1
现在可以使用Array.prototype.flatMap()(具有不同的支持)一步完成此操作。 - James Elderfield

5

对于通过搜索引擎到达此处且想要 Lodash 选项的人:

_.compact(_.flatten(_.zip(array1, array2)))

2

试试这样:

function merge(array1, array2) {
  if (array1.length == array2.length) {
    var c = [];
    for (var i = 0; i < array1.length; i++) {
      c.push([array1[i], array2[i]]);
    }
    return c;
  }
  return null;
}

1
不是在抱怨什么,但这可以很容易地通过使用不同长度的数组来完成。 - Rodik
7
jQuery 不够用了(啊,终于有一个正当理由这么说)。 - raina77ow
肯定可以做到,但这个想法首先浮现在我的脑海中,所以我尝试了一下!!! - Rahul Tripathi
为了匹配指定的格式,你应该将 c.push([array1[i], array2[i]]) 改成 c.push(array1[i], array2[i]) - omikes

1

我来到这里是因为好奇是否有一个new Array.prototype.<whatever>()对于这很有帮助,flatMap就是它... 有点儿 - 但我将使用最简单、最明显的解决方案离开...
(还有一些泪水,因为在十年后没有人用for循环构建单个数组)

普通老式JavaScript

如果你要合并像立体声通道或模板字符串之类的东西,那么你只需要这个:

// Supports the two most common cases:
//   - interleaving left and right audio channels
//   - interleaving template string and values
// (right is assumed to be the same length as left, or one shorter)
function interleave(left, right) {

  var both = [];
  var i;

  for (i = 0; i < left.length; i += 1) {
    both.push(left[i]);

    // because a template string will have one fewer value
    // than it will have string parts
    if (i < right.length) {
      both.push(right[i]);
    }
  }

  return both;
}

// a template string will always have one extra item
var abc = ['a', 'b', 'c', 'd' ];
var one = [1, 2, 3 ];

var both = interleave(abc, one);
console.log(both);
// ['a', 1, 'b', 2, 'c', 3, 'd']

flatMap

如评论中所述,这可能是合适的:

function cleverInterleave() {
  return abc.flatMap(function (val, i) {
    if (one[i]) {
      return [val, one[i]];
    }
    return [val];
  });
}

var abc = ['a', 'b', 'c', 'd' ];
var one = [1, 2, 3 ];

cleverInterleave(abc, one);
// ['a', 1, 'b', 2, 'c', 3, 'd']

然而,这似乎有点太“聪明”了,不够直观。也不够高效...但对于大多数代码来说,可读性比效率更重要,所以...两个缺点。

频道越多,问题越多

您还可以创建一个更通用的形式来处理任意数量的数组,或者压缩长度不均匀的数组。

然而,我建议使用类似的模式,但针对您实际需要的数组数量进行调整 - 例如RGB为3,RGBA为4等。


0

如果您:

  1. 没有保证长度相同的数组。
  2. 无法保证第一个数组比第二个数组长。
  3. 无需依赖库。

则可以使用以下方法:

function interleave(a, b) {
  const interleaved = [];
  const lenA = a.length;
  const lenB = b.length;
  const len = Math.max(lenA, lenB);
  let i = 0;
  while (i < len) {
    if (lenA > i) interleaved.push(a[i]);
    if (lenB > i) interleaved.push(b[i]);
    i++;
  }
  return interleaved;
}

// Examples
const sameLength = interleave([1, 2], ['A', 'B']);
const aIsLonger = interleave([1, 2], ['A']);
const bIsLonger = interleave([1], ['A', 'B']);
const aIsEmpty = interleave([], ['A', 'B']);
const bIsEmpty = interleave([1, 2], []);

console.log('sameLength', sameLength);
console.log('aIsLonger', aIsLonger);
console.log('bIsLonger', bIsLonger);
console.log('aIsEmpty', aIsEmpty);
console.log('bIsEmpty', bIsEmpty);

我认识到这个问题发布已经快12年了,特别提到了jQuery,所以出于这个原因你可能想选择另一个答案,但我并没有把它强行塞进这个解决方案中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接