So erstellen Sie Arrays aus einem Array [geschlossen]

33

Ich bin ein JavaScript-Anfänger und versuche, zwei verschiedene Arrays mit Werten aus einem Hauptarray zu erstellen.

Mein Hauptarray sieht aus wie:

0: Array(3) [ 2011, 127072.7, 51584 ]
1: Array(3) [ 2012, 125920.3, 59974 ]
2: Array(3) [ 2013, 129305.4, 15468 ]
3: Array(3) [ 2014, 135364, 84554 ]
4: Array(3) [ 2015, 136757, 98754 ]
5: Array(3) [ 2016, 155653.5, 155548 ]
6: Array(3) [ 2017, 164130.5, 284848 ]

Und ich muss zwei Arrays erstellen, die zuerst so aussehen:

0: Array(2) [ 2011, 127072.7]
1: Array(2) [ 2012, 125920.3]
2: Array(2) [ 2013, 129305.4]
3: Array(2) [ 2014, 135364]
4: Array(2) [ 2015, 136757]
5: Array(2) [ 2016, 155653.5]
6: Array(2) [ 2017, 164130.5]

(erster und zweiter Wert)

und zweitens wie:

0: Array(2) [ 2011, 51584]
1: Array(2) [ 2012, 59974]
2: Array(2) [ 2013, 15468]
3: Array(2) [ 2014, 84554]
4: Array(2) [ 2015, 98754]
5: Array(2) [ 2016, 155548]
6: Array(2) [ 2017, 284848]

(erster und dritter Wert)

Ich versuche Spleißen, Filtern usw., aber ich weiß nicht, wie ich anfangen soll.

Es ist nicht notwendig, mir eine genaue Lösung zu schreiben, sondern nur Schritte, wie es geht.

Dominik Lev
quelle
Vielen Dank für die tollen Antworten. Sie arbeiten großartig. Ich habe vielleicht eine Frage für die Zukunft. Kann man das so machen, dass es nicht auf zwei Felder festgelegt ist? Aber auch drei, vier usw.?
Dominik Lev
3
Was ist das eigentliche Problem, das Sie hier lösen möchten? Es scheint wahrscheinlich, dass die Verwendung eines Arrays von Objekten die bessere Option ist.
BlueRaja - Danny Pflughoeft
Vorschlag: Anstatt explizite aufeinanderfolgende Jahre in Ihrem Array zu haben, könnte das Jahr von einem bestimmten Startpunkt aus implizit sein. Dann benötigen Sie nur einen skalaren Startpunkt, und das Jahr für jedes Element ist anhand seines Array-Index bekannt. (Funktioniert nur, wenn Ihre Jahre wie in diesem Beispiel immer zusammenhängend und in aufsteigender Reihenfolge sind. Dies vereinfacht sich jedoch gut von einer Reihe von Paaren zu einer Reihe von primitiven Zahlen.)
Peter Cordes

Antworten:

29

Sie können einen dynamischen Ansatz wählen und alle Elemente des Arrays nach dem Schlüsselwert für jedes neue Array abrufen.

var data = [[2011, 127072.7, 51584], [2012, 125920.3, 59974], [2013, 129305.4, 15468], [2014, 135364, 84554], [2015, 136757, 98754], [2016, 155653.5, 155548], [2017, 164130.5, 284848]],
    [first, second] = data.reduce(
        (r, [k, ...a]) => {
            a.forEach((v, i) => r[i].push([k, v]));
            return r;
        },
        Array.from({ length: Array.isArray(data[0]) ? data[0].length - 1 : 0 }, () => [])
    );

console.log(first);
console.log(second);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Nina Scholz
quelle
Vielen Dank für eine tolle Antwort. Kann ich eine Frage für die Zukunft haben? Ist es möglich, es nicht nur auf 2 Arrays, sondern auch auf mehr zu reparieren?
Dominik Lev
1
Sie können ersetzen [first, second]mit arrayund Sie erhalten Arrays mit allen Spalten der Daten als Arrays.
Nina Scholz
2
Stattdessen r[i] = r[i] || []sollten Sie nur langsam Array.from({length: (data[0]?.length ?? 1) - 1}, () => [])für den anfänglichen Akkumulatorwert verwenden
Bergi
3
@NinaScholz Nein, ich meinte, Sie überprüfen, ob r[i]in jeder Schleifeniteration vorhanden ist, während Sie einfach die erforderlichen Ergebnisarrays außerhalb des reduceAufrufs erstellen können .
Bergi
1
@Klaycon Nein, Array-Zugriffe außerhalb der Array-Grenzen sind sehr langsam, daher funktioniert "Überprüfen, ob bereits vorhanden" nicht gut. Mein Kommentar sollte sich nicht um die Leistung kümmern, sondern sauberen und vorhersehbaren (korrekten) Code bevorzugen. Ich schrieb zuerst "ziemlich hässlich und langsam", bevor mir klar wurde, dass mein Vorschlag, der den Umgang mit dem leeren Fall explizit macht, auch keine wirkliche Schönheit ist.
Bergi
14

Sie können verwenden .map(), um Ihre Daten zu durchlaufen und eine Array-Destrukturierung zu verwenden, um die gewünschte Ausgabe zu erhalten:

const data = [
  [ 2011, 127072.7, 51584 ],
  [ 2012, 125920.3, 59974 ],
  [ 2013, 129305.4, 15468 ],
  [ 2014, 135364, 84554 ],
  [ 2015, 136757, 98754 ],
  [ 2016, 155653.5, 155548 ],
  [ 2017, 164130.5, 284848 ]
];

const arr1 = data.map(([year, val]) => ([year, val]));
const arr2 = data.map(([year, _, val]) => ([year, val]));

console.log(arr1);
console.log(arr2);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Mohammad Usman
quelle
Vielen Dank für eine tolle Antwort. Kann ich eine Frage für die Zukunft haben? Ist es möglich, es nicht nur auf 2 Arrays, sondern auch auf mehr zu reparieren?
Dominik Lev
1
@DominikLev In diesem Fall können Sie die Antwort von Nina verwenden. Es ist gut.
Mohammad Usman
1
Dies kann mithilfe der([year, ...values]) => [year, values[n]]
Restparametersyntax
@JollyJoker - Sie sollten das als Antwort posten, das ist eine wirklich schöne und prägnante allgemeine Lösung
Filip Milovanović
@ FilipMilovanović Ich habe bereits stackoverflow.com/a/60166014/7126740
JollyJoker
6

Sie können Array.prototype.forEachdie Elemente des ursprünglichen Arrays durchlaufen, dann die neuen Elemente erstellen und in neue Arrays verschieben:

var original = [[ 2011, 127072.7, 51584 ], [ 2012, 125920.3, 59974 ], [ 2013, 129305.4, 15468 ]]

var array1 = []
var array2 = []

original.forEach(item => {
  array1.push([item[0], item[1]]);
  array2.push([item[0], item[2]]);
});

console.log(array1);
console.log(array2);

Ausgabe:

Geben Sie hier die Bildbeschreibung ein


Dynamisches Generieren unserer Arrays, damit die Lösung funktioniert, unabhängig davon, wie viele Elemente die ursprünglichen Arrays enthalten:

var original = [
  [2011, 127072.7, 51584, 1, 2, 3],
  [2012, 125920.3, 59974, 4, 5, 6],
  [2013, 129305.4, 15468, 7, 8, 9]
]

// Array of arrays
var myArray = []

// Fill it with empty arrays
for (var i = 0; i < original[0].length - 1; i++)
  myArray.push([])

// Iterate over original
// For each original, insert the first and i-th element into our array of arrays
original.forEach(item => {
  for (var i = 1; i < item.length; i++) {
    myArray[i - 1].push([item[0], item[i]]);
  }
});

console.log(myArray);

Ausgabe: Geben Sie hier die Bildbeschreibung ein

Ismael Padilla
quelle
Vielen Dank für eine tolle Antwort. Kann ich eine Frage für die Zukunft haben? Ist es möglich, es nicht nur auf 2 Arrays, sondern auch auf mehr zu reparieren?
Dominik Lev
1
Es ist möglich, die Arrays dynamisch zu generieren, ohne vorher zu wissen, wie viele Elemente die ursprünglichen Arrays haben werden. Schauen Sie sich meine bearbeitete Antwort an :)
Ismael Padilla
4

Zunächst haben Sie am Anfang ein Array von Arrays. Sie können mapdieses Array in zwei verschiedene Arrays destructuringumwandeln, indem Sie jeden Wert auf präzise Weise aus den Subarrays abrufen:

const data = [
  [ 2011, 127072.7, 51584 ],
  [ 2012, 125920.3, 59974 ],
  [ 2013, 129305.4, 15468 ],
  [ 2014, 135364, 84554 ],
  [ 2015, 136757, 98754 ],
  [ 2016, 155653.5, 155548 ],
  [ 2017, 164130.5, 284848 ],
];

const array1 = data.map(([first, second, third]) => [first, second]);
const array2 = data.map(([first, second, third]) => [first, third]);

console.log(JSON.stringify(array1));
console.log(JSON.stringify(array2));

Alberto Trindade Tavares
quelle
4

Durchlaufen Sie das Hauptarray und geben Sie ein neues Array zurück, indem Sie feste Indexwerte verwenden, um auf die Werte Ihrer untergeordneten Arrays zuzugreifen.

const multiDimArr = [
  [2011, 127072.7, 51584],
  [2012, 125920.3, 59974],
  [2013, 129305.4, 15468],
  [2014, 135364, 84554],
  [2015, 136757, 98754],
  [2016, 155653.5, 155548],
  [2017, 164130.5, 284848],
]

const arr1= multiDimArr.map(x=>[x[0],x[1]]);
const arr2= multiDimArr.map(x=>[x[0],x[2]]);

console.log(arr1)
console.log(arr2)

Eugen Sunic
quelle
3

Sie können die Funktion Reduzieren wie folgt verwenden, die nur einmal wiederholt wird:

let matrix = [[ 2011, 127072.7, 51584 ],[ 2012, 125920.3, 59974 ],[ 2013, 129305.4, 15468 ],[ 2014, 135364, 84554 ],[ 2015, 136757, 98754 ],[ 2016, 155653.5, 155548 ],[ 2017, 164130.5, 284848 ]];

let result = matrix.reduce((a, [year, k, v]) => {
  a.second.push([year, k]);
  a.third.push([year, v]);
  return a;
}, {second: [], third: []});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Ele
quelle
Warum das CSS in dieser Antwort?
Joshua Fox
1
@JoshuaFox nur zum Erweitern der Höhe der Konsole.
Ele
3

Bitte schön

let values = [[ 2011, 127072.7, 51584 ],[ 2012, 125920.3, 59974 ],[ 2013, 129305.4, 15468 ],[ 2014, 135364, 84554 ],[ 2015, 136757, 98754 ],[ 2016, 155653.5, 155548 ],[ 2017, 164130.5, 284848 ]];

let chunk1 = values.map(arr1 => {
  return [arr1[0], arr1[1]]
});
let chunk2 = values.map(arr1 => {
  return [arr1[0], arr1[2]]
})

console.log("Chunk 1", chunk1);
console.log("Chunk 2", chunk2);

Muhammad Zeeshan
quelle
2

Ich habe Map for Loop verwendet, zwei Arrays, um die benötigten Werte zu pushen.

let point_table = []
let integer_table = []
const historical_table = [
  [2011, 127072.7, 51584],
  [2012, 125920.3, 59974],
  [2013, 129305.4, 15468],
  [2014, 135364, 84554],
  [2015, 136757, 98754],
  [2016, 155653.5, 155548],
  [2017, 164130.5, 284848]
]
historical_table.map(row => {
  point_table.push([row[0], row[1]])
  integer_table.push([row[0], row[2]])
})
console.log(point_table, integer_table)

iEfimoff
quelle
1

eine andere Lösung :

 const original= [  [ 2011, 127072.7, 51584 ], [ 2012, 125920.3, 59974 ],[ 2013, 129305.4, 15468 ],  [ 2014, 135364, 84554 ],  [ 2015, 136757, 98754 ],  [ 2016, 155653.5, 155548 ],  [ 2017, 164130.5, 284848 ]];

original.map (x => [[x [0], x [1]], [x [0], x [2]]) .reduce ((a, b) => a.concat (b), [])

Cem Tuğut
quelle
1

Für die generische Lösung bietet das Erstellen eines Indexarrays für die Wertespalten eine einfache Möglichkeit, die vollständigen Daten den gewünschten Arrays zuzuordnen.

[...data[0].keys()].slice(0,-1)

gibt Ihnen eine Reihe von Indizes abzüglich der einen Spalte, die das Jahr war, und

n => data.map(([year, ...values]) => [year, values[n]])

gibt Ihnen das gewünschte Array für die n-te Wertespalte. Damit:

var data = [[2011, 127072.7, 51584], [2012, 125920.3, 59974], [2013, 129305.4, 15468], [2014, 135364, 84554], [2015, 136757, 98754], [2016, 155653.5, 155548], [2017, 164130.5, 284848]]

const yearArrays = arr => [...arr[0].keys()].slice(0,-1)
       .map(arr.map(([year, ...values]) => [year, values[n]]))

console.log(yearArrays(data));
.as-console-wrapper { max-height: 100% !important; top: 0; }

JollyJoker
quelle
0

Eine weitere Lösung für Eingabearrays mit generischer Länge.

const input = [[1,11,111,1111],[2,22,222,2222]];

const result = input.reduce((accumulator, [head, ...tail]) => {
  tail.forEach((item, index) => {
    accumulator[index] = accumulator[index] || [];
    accumulator[index].push([head, item]);
  });
  return accumulator;
}, [])

console.log(result);

Linus
quelle
0

Verwenden Sie diese Lösung, um eine generische Kombination aus einem vorhandenen mehrdimensionalen Array zu erstellen. Sie müssen den Index der Elemente übergeben, aus denen explizit ausgewählt werden soll, und das macht ihn generisch.

    const multiDimArr = [
      [2011, 127072.7, 51584],
      [2012, 125920.3, 59974],
      [2013, 129305.4, 15468],
      [2014, 135364, 84554],
      [2015, 136757, 98754],
      [2016, 155653.5, 155548],
      [2017, 164130.5, 284848],
    ]


    function arrayCombo (idxA, idxB){
      return multiDimArr.map(x=>[x[idxA],x[idxB]]);
    }

    console.log(arrayCombo(0, 1));
    console.log(arrayCombo(0, 2));
    console.log(arrayCombo(1, 2));

rach8garg
quelle