it-swarm.com.ru

Объединить два массива с чередующимися значениями

я хотел бы объединить 2 массива разной длины:

let array2 = ["a", "b", "c", "d"];
let array2 = [1, 2];

let outcome = ["a",1 ,"b", 2, "c", "d"] 

Какой лучший способ сделать это? 

Правка: Результат, который я ожидаю, ["a", 1 ,"b", 2, "c", "d"]

8
Fargho

Вы можете перебрать минимальную длину как массива, так и построить альтернативные элементы, а в конце выдвинуть остальные.

var array1 = ["a", "b", "c", "d"],
    array2 = [1, 2],
    result = [],
    i, l = Math.min(array1.length, array2.length);
    
for (i = 0; i < l; i++) {
    result.Push(array1[i], array2[i]);
}
result.Push(...array1.slice(l), ...array2.slice(l));

console.log(result);

Решение для произвольного подсчета массивов с помощью алгоритма транспонирования и последующего выравнивания.

var array1 = ["a", "b", "c", "d"],
    array2 = [1, 2],
    result = [array1, array2]
        .reduce((r, a) => (a.forEach((a, i) => (r[i] = r[i] || []).Push(a)), r), [])
        .reduce((a, b) => a.concat(b));
    
console.log(result);

7
Nina Scholz

Создайте массив кортежей. Каждый кортеж содержит 1 элемент из каждого массива, сглаживая его путем распределения массива кортежей и добавления оставшихся элементов из массивов:

const a1 = ["a", "b", "c", "d"];
const a2 = [1,2];
const l = Math.min(a1.length, a2.length);

const merged = [].concat(...Array.from({ length: l }, (_, i) => [a1[i], a2[i]]), a1.slice(l), a2.slice(l));
  
console.log(merged);

6
Ori Drori

Вот еще один способ сделать это, используя деструктурирующее назначение

const interleave = ([x,...xs], [y,...ys]) =>
  x === undefined && y === undefined
    ? []
    : x === undefined
      ? [y] .concat (ys)
      : y === undefined
        ? [x] .concat (xs)
        :  [x, y] .concat (interleave (xs, ys))
    

console.log (interleave ([0, 2, 4, 6], [1, 3, 5])) // [ 0 1 2 3 4 5 6 ]    
console.log (interleave ([0, 2, 4], [1, 3, 5, 7])) // [ 0 1 2 3 4 5 7 ]
console.log (interleave ([0, 2, 4], []))           // [ 0 2 4 ]
console.log (interleave ([], [1, 3, 5, 7]))        // [ 1 3 5 7 ]
console.log (interleave ([], []))                  // [ ]

И здесь он использует правильный хвостовой вызов

const interleave = ([x,...xs], [y,...ys], acc = []) =>
  x === undefined && y === undefined
    ? acc
    : x === undefined
      ? acc.concat (y, ys)
      : y === undefined
        ? acc.concat (x, xs)
        : interleave (xs, ys, acc.concat ([x, y]))

console.log (interleave ([0, 2, 4, 6], [1, 3, 5])) // [ 0 1 2 3 4 5 6 ]    
console.log (interleave ([0, 2, 4], [1, 3, 5, 7])) // [ 0 1 2 3 4 5 7 ]
console.log (interleave ([0, 2, 4], []))           // [ 0 2 4 ]
console.log (interleave ([], [1, 3, 5, 7]))        // [ 1 3 5 7 ]
console.log (interleave ([], []))                  // [ ]

И снова без использования деструктурирующего задания

const interleave = (xs, ys, acc = []) =>
  xs.length === 0 && ys.length === 0
    ? acc
    : xs.length === 0
      ? acc.concat (ys)
      : ys.length === 0
        ? acc.concat (xs)
        : interleave (xs.slice (1), ys.slice (1), acc.concat ([xs[0], ys[0]]))

console.log (interleave ([0, 2, 4, 6], [1, 3, 5])) // [ 0 1 2 3 4 5 6 ]
console.log (interleave ([0, 2, 4], [1, 3, 5, 7])) // [ 0 1 2 3 4 5 7 ]
console.log (interleave ([0, 2, 4], []))           // [ 0 2 4 ]
console.log (interleave ([], [1, 3, 5, 7]))        // [ 1 3 5 7 ]
console.log (interleave ([], []))                  // [ ]

Или комбинация хвостового вызова и вашего индекса - этот самый быстрый по сравнению с другими предоставленными мною фрагментами, так как он выделяет меньше всего ресурсов, создает наименьшее количество промежуточных значений и, следовательно, уменьшает сборку мусора после вычисления - win/win/выиграть

const interleave = (xs, ys, i = 0, acc = []) =>
  xs.length === i && ys.length === i
    ? acc
    : xs.length === i
      ? acc.concat (ys.slice (i))
      : ys.length === i
        ? acc.concat (xs.slice (i))
        : interleave (xs, ys, i + 1, acc.concat ([xs[i], ys[i]]))

console.log (interleave ([0, 2, 4, 6], [1, 3, 5])) // [ 0 1 2 3 4 5 6 ]
console.log (interleave ([0, 2, 4], [1, 3, 5, 7])) // [ 0 1 2 3 4 5 7 ]
console.log (interleave ([0, 2, 4], []))           // [ 0 2 4 ]
console.log (interleave ([], [1, 3, 5, 7]))        // [ 1 3 5 7 ]
console.log (interleave ([], []))                  // [ ]

Любитель заметит, что i и acc являются утечкой частного API - это можно легко исправить с помощью помощника loop; обратите внимание, что этот метод также делает interleave стековым безопасным в среде без оптимизации хвостовых вызовов

Таким образом, по сравнению с вышеизложенным, мы получаем два больше выигрышей, делая этот выигрыш/выигрыш/выигрыш/выигрыш/выигрыш

const recur = (...values) =>
  ({ type: recur, values })
  
const loop = f =>
  {
    let acc = f ()
    while (acc && acc.type === recur)
      acc = f (...acc.values)
    return acc
  }

const interleave = (xs, ys) =>
  loop ((i = 0, acc = []) =>
    xs.length === i && ys.length === i
      ? acc
      : xs.length === i
        ? acc.concat (ys.slice (i))
        : ys.length === i
          ? acc.concat (xs.slice (i))
          : recur (i + 1, acc.concat ([xs[i], ys[i]])))

console.log (interleave ([0, 2, 4, 6], [1, 3, 5])) // [ 0 1 2 3 4 5 6 ]
console.log (interleave ([0, 2, 4], [1, 3, 5, 7])) // [ 0 1 2 3 4 5 7 ]
console.log (interleave ([0, 2, 4], []))           // [ 0 2 4 ]
console.log (interleave ([], [1, 3, 5, 7]))        // [ 1 3 5 7 ]
console.log (interleave ([], []))                  // [ ]

5
user633183

ONELINER: я предполагаю, что x=array1, y=array2, x и y могут быть произвольными

[...x,...y].reduce((l,c,i)=>(i<x.length&&l.Push(x[i]),i<y.length&&l.Push(y[i]),l),[])

рабочий пример (для 3 случаев)

0
Kamil Kiełczewski

Ты можешь сделать:

const array1 = ["a", "b", "c", "d"];
const array2 = [1, 2];
const mergeArrays = (a, b) => (a.length > b.length ? a : b)
  .reduce((acc, cur, i) => a[i] && b[i] ? [...acc, a[i], b[i]] : [...acc, cur], []);

console.log(mergeArrays(array1, array2)); // ["a",1 ,"b", 2, "c", "d"]

0
Yosvel Quintero