Zip-Arrays in JavaScript?

Lesezeit: 6 Minuten

Benutzeravatar von userMod2
userMod2

Ich habe 2 Arrays:

var a = [1, 2, 3]
var b = [a, b, c]

Was ich als Ergebnis erhalten möchte ist:

[[1, a], [2, b], [3, c]]

Es scheint einfach, aber ich kann einfach nicht herausfinden.

Ich möchte, dass das Ergebnis ein Array ist, in dem jedes der Elemente aus den beiden Arrays zusammengezippt ist.

  • Beachten Sie, dass Array map() in IE8 nicht unterstützt wird, falls dies ein Problem darstellt. Polyfill hier developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

    – Tim Hayes

    25. Februar 2014 um 13:37 Uhr

  • Diese Frage ist KEIN Duplikat, da sie nur danach fragt 2 Arrays statt gezippt werden N Arrays. Es handelt sich also um einen Sonderfall, für den es spezialisierte, performantere Lösungen gibt.

    – le_m

    4. Juni 2016 um 0:52 Uhr

Benutzeravatar von tewathia
tewathia

Verwenden Sie die map Methode:

var a = [1, 2, 3]
var b = ['a', 'b', 'c']

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

console.log(c)

DEMO

  • Absoluter Javascript-Noob hier, aber ich hatte den Eindruck, dass der Index vor dem Element stehen muss? das heißt, .map (Funktion (Index, Element))?

    – Ausreißer

    29. Oktober 2016 um 11:05 Uhr

  • @runawaykid Die Antwort ist richtig. Du kannst das … sehen MDN-Map-Dokumentation zum Callback-Parameter. Parameter sind (in der Reihenfolge): currentvalue, index, array

    – icc97

    6. Januar 2017 um 15:22 Uhr

  • Noch schöner ist die Verwendung der Pfeilnotation: var c = a.map((e, i) => [e, b[i]]);

    – Marczoide

    15. November 2017 um 10:39 Uhr


  • Wie würden Sie daraus ein Wörterbuch/Objekt erstellen?

    – Höhepunkt

    26. April 2018 um 6:50 Uhr

  • Beachten Sie nur, dass, wenn die Arrays unterschiedliche Längen haben, dies entweder die rechte Seite mit undefinierten Werten auffüllt (if a ist länger) oder lässt einige Einträge aus (falls b ist länger).

    – ErikE

    19. Februar 2020 um 18:56 Uhr

Benutzeravatar von Roko C. Buljan
Roko C. Buljan

Zip-Arrays von die gleiche Länge:

Verwenden Array.prototype.map()

const zip = (a, b) => a.map((k, i) => [k, b[i]]);

console.log(zip([1,2,3], ["a","b","c"]));
// [[1, "a"], [2, "b"], [3, "c"]]

Zip-Arrays unterschiedlicher Länge:

Verwenden Array.from()

const zip = (a, b) => Array.from(Array(Math.max(b.length, a.length)), (_, i) => [a[i], b[i]]);

console.log( zip([1,2,3], ["a","b","c","d"]) );
// [[1, "a"], [2, "b"], [3, "c"], [undefined, "d"]]

Verwenden Array.prototype.fill() Und Array.prototype.map()

const zip = (a, b) => Array(Math.max(b.length, a.length)).fill().map((_,i) => [a[i], b[i]]);

console.log(zip([1,2,3], ["a","b","c","d"]));
// [[1, "a"], [2, "b"], [3, "c"], [undefined, "d"]]

Mehrere Zips (N) Arrays:

const zip = (...arr) => Array(Math.max(...arr.map(a => a.length))).fill().map((_,i) => arr.map(a => a[i]));  
console.log(zip([1,2], [3,4], [5,6])); // [[1,3,5], [2,4,6]]

  • Danke dafür. Glücklicherweise hat die Karte in meiner Umgebung funktioniert, aber ich habe diese Methode für alle Fälle aufgezeichnet.

    – userMod2

    26. Februar 2014 um 13:05 Uhr

  • Elegant, aber fehlerhaft. Classic zip muss kommutativ sein, diese Implementierung ist es nicht. Check out mit Arrays unterschiedlicher Länge.

    – goteguru

    11. November 2020 um 10:11 Uhr

  • Danke @goteguru, ich habe zwei weitere Beispiele für Arrays unterschiedlicher Länge hinzugefügt.

    – Roko C. Buljan

    11. November 2020 um 18:28 Uhr

  • Danke @RokoC.Buljan, schön. Ich denke jedoch, dass es Math.min sein sollte. zip stammt aus den funktionalen Sprachen (genau wie Filter, Map, Reduce und Co.) und sein Hauptzweck besteht darin, zwei Streams in eine binäre Berechnung einzuspeisen. Fehlt einer davon, ist das Ergebnis ohnehin undefiniert, daher sollten wir frühzeitig aufhören. Darüber hinaus können die Streams in FP unendlich (!) sein, was bedeuten würde, dass der obige Algorithmus niemals stoppt. Natürlich ist es bei der Verwendung von js-Arrays nicht der Fall, aber dies ist immer noch das klassische “Zip”. (In Bezug auf die Leistung: Stellen Sie sich vor, ein Array hat 100.000 Elemente und das andere nur zwölf).

    – goteguru

    12. November 2020 um 20:20 Uhr


  • Dies ist die richtige Antwort auf die Frage und nicht die, die OP akzeptiert hat.

    – Wladimir Despotovic

    2. März 2022 um 11:03 Uhr

Benutzeravatar von Mushroomator
Mushroomator

Zippen durch Nutzung von Generatorfunktionen

Sie können auch eine verwenden Generatorfunktion Zu zip().

const a = [1, 2, 3]
const b = ['a', 'b', 'c']

/**
 * Zips any number of arrays. It will always zip() the largest array returning undefined for shorter arrays.
 * @param  {...Array<any>} arrays 
 */
function* zip(...arrays){
  const maxLength = arrays.reduce((max, curIterable) => curIterable.length > max ? curIterable.length: max, 0);
  for (let i = 0; i < maxLength; i++) {
    yield arrays.map(array => array[i]);
  }
}

// put zipped result in an array
const result = [...zip(a, b)]

// or lazy generate the values
for (const [valA, valB] of zip(a, b)) {
  console.log(`${valA}: ${valB}`);  
}
.as-console-wrapper { max-height: 100% !important; top: 0; }

Das obige funktioniert für eine beliebige Anzahl von Arrays und wird zip() das längste Array so undefined wird als Wert für kürzere Arrays zurückgegeben.

Reißverschluss von allen Iterables

Hier eine Funktion die für alle nutzbar ist Iterables (z.B Maps, Sets oder Ihre Gewohnheit Iterable), nicht nur Arrays.

const a = [1, 2, 3];
const b = ["a", "b", "c"];

/**
 * Zips any number of iterables. It will always zip() the largest Iterable returning undefined for shorter arrays.
 * @param  {...Iterable<any>} iterables
 */
function* zip(...iterables) {
  // get the iterator of for each iterables
  const iters = [...iterables].map((iterable) => iterable[Symbol.iterator]());
  let next = iters.map((iter) => iter.next().value);
  // as long as any of the iterables returns something, yield a value (zip longest)
  while(anyOf(next)) {
    yield next;
    next = iters.map((iter) => iter.next().value);
  }

  function anyOf(arr){
    return arr.some(v => v !== undefined);
  }
}

// put zipped result in aa array
const result = [...zip(a, new Set(b))];

// or lazy generate the values
for (const [valA, valB] of zip(a, new Set(b))) {
  console.log(`${valA}: ${valB}`);
}

Natürlich wäre es auch möglich, nur zu verwenden [...Iterable] irgendwelche umzuwandeln Iterable zu einem Array und verwenden Sie dann die erste Funktion.

Verwendung der reduce Methode:

const a = [1, 2, 3]
const b = ['a', 'b', 'c']

var c = a.reduce((acc, curr, ind) => {
  acc.push([curr, b[ind]]);
  return acc;
}, []);
console.log(c)

Mit forEach Methode:

const a = [1, 2, 3]
const b = ['a', 'b', 'c']
const c = [];
a.forEach((el, ind) => {
    c.push([el, b[ind]])
});
console.log(c)

Bereitstellung einer Lösung mit zwingender Programmierung auf einfache Weise for loop.

Dies funktioniert besser, wenn Sie dies tun Reißverschluss Betrieb an riesig Daten Sets im Vergleich zu den bequemen Array-Funktionen wie map() Und forEach().

Beispiel:

const a = [1, 2, 3];
const b = ['a', 'b', 'c'];
const result = [];
for (let i = 0; i < a.length; i++) {
  result.push([a[i], b[i]]);
}
console.log(result);

Und wenn Sie eine 1-Linie wollen einfacher Lösung dann können Sie eine Bibliothek wie verwenden Ramda das hat ein Reißverschluss Funktion.

Beispiel:

const a = [1, 2, 3];
const b = ['a', 'b', 'c'];
const result = R.zip(a, b);
console.log(result);

1442210cookie-checkZip-Arrays in JavaScript?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy