2017-11-01 106 views
8

chciałbym scalić 2 tablice o różnej długości:Scalanie dwóch tablic z naprzemiennych wartości

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

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

Co najlepszym sposobem, aby to zrobić?

Edit: Wynik spodziewałbym jest ["a", 1 ,"b", 2, "c", "d"]

+3

co masz na myśli z "*, co jest najlepszym sposobem na to *"? Jaki jest oczekiwany wynik? "scalanie" jest dość szeroką koncepcją. –

+1

Czy możesz napisać, jak powinien wyglądać efekt końcowy? – noitse

+0

według naprzemiennych wartości masz na myśli jak 1 z tablicy 1, a następnie z tablicy 2 i tak dalej? – schylake

Odpowiedz

7

Można iteracyjne długość min zarówno tablicy i budować naprzemienne elementy, a na koniec popchnij resztę.

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

Roztwór do dowolnej liczby tablic z algorytmem transpozycji i później spłaszczenie.

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

5

Utwórz tablicę krotek. Każda krotka zawiera 1 pierwiastek z każdej tablicy, spłaszczyć poprzez rozłożenie wachlarz krotek, a dodanie resztki elementów z tablic:

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

+0

Array.from() z .filter() wziąć 4,044921875ms i result.push() wziąć 3,296630859375ms –

3

Oto kolejny sposób można to zrobić za pomocą destructuring zadanie

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 ([], []))     // [ ]

I tu jest za pomocą odpowiedniego połączenia ogon

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 ([], []))     // [ ]

I znowu bez użycia destructuring zadanie

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 ([], []))     // [ ]

lub kombinacja rozmowy ogonowej i indeksu - ten jest najszybszy w porównaniu do innych fragmentów ja Pod warunkiem, że tworzy najmniej alokacji, tworzy najmniej wartości pośrednich, a tym samym mniej po śmieciach obliczeniowych kolekcja - Win/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 ([], []))     // [ ]

keen zauważy, że i i acc są wyciekły prywatne API - może to być łatwo usunięte przy użyciu loop pomocnika; Uwaga ta technika sprawia również interleave stos bezpieczny w non-tail-call-zoptymalizowane środowisko

So porównaniu do powyższego, możemy uzyskać dwa więcej wygranych, dzięki tej wygranej/win/win/win/win

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 ([], []))     // [ ]