Come creare array dall'array [chiuso]


33

Sono un principiante di JavaScript e sto provando a creare due array diversi con valori da un array principale.

Il mio array principale è simile a:

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 ]

E ho bisogno di creare due array, prima assomigliando a:

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]

(primo e secondo valore)

e secondo come:

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]

(primo e terzo valore)

Sto provando la giunzione, il filtro ecc. Ma non so come iniziare.

Non è necessario che mi scriva una soluzione esatta, ma solo passaggi su come farlo.


Grazie mille per le ottime risposte. Funzionano benissimo. Potrei avere una domanda per il futuro. Può essere fatto in modo che non sia fisso su due campi? Ma anche tre, quattro, ecc.?
Dominik Lev,

3
Qual è il vero problema che stai cercando di risolvere qui? Sembra probabile che l'uso di una matrice di oggetti sia l'opzione migliore.
BlueRaja - Danny Pflughoeft l'

Suggerimento: invece di avere anni consecutivi espliciti nell'array, è possibile che l'anno sia implicito da un determinato punto di partenza. Quindi è necessario solo un punto di partenza scalare e l'anno per ogni elemento è noto in base al suo indice di matrice. (Funziona solo se i tuoi anni sono sempre contigui e in ordine crescente come questo esempio. Ma semplifica piacevolmente da una matrice di coppie a una matrice di numeri primitivi.)
Peter Cordes,

Risposte:


29

È possibile adottare un approccio dinamico e ottenere tutti gli elementi dell'array dopo il valore chiave per ciascun nuovo array.

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


Grazie mille per un'ottima risposta. Posso avere una domanda per il futuro? È possibile risolverlo non solo su 2 array ma anche su altri?
Dominik Lev,

1
è possibile sostituirlo [first, second]con arraye si ottengono matrici con tutte le colonne dei dati come matrici.
Nina Scholz,

2
Invece di quello piuttosto lento r[i] = r[i] || [], dovresti semplicemente usare Array.from({length: (data[0]?.length ?? 1) - 1}, () => [])il valore iniziale dell'accumulatore
Bergi,

3
@NinaScholz No, intendevo dire che stai verificando se r[i]esiste in ogni iterazione di loop, mentre potresti semplicemente creare le matrici di risultati necessarie al di fuori della reducechiamata.
Bergi,

1
@Klaycon No, gli accessi all'array fuori dai limiti dell'array sono super lenti, quindi "controlla se esiste già" non funziona bene. Il mio commento non intendeva preoccuparmi delle prestazioni, ma preferire un codice pulito e prevedibile (corretto). Ho prima scritto "piuttosto brutto e lento" prima di rendermi conto che il mio suggerimento che rende esplicito il trattamento del caso vuoto non è nemmeno una vera bellezza.
Bergi,

14

È possibile utilizzare .map()per scorrere i dati e utilizzare la ristrutturazione dell'array per ottenere l'output desiderato:

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


Grazie mille per un'ottima risposta. Posso avere una domanda per il futuro? È possibile risolverlo non solo su 2 array ma anche su altri?
Dominik Lev,

1
@DominikLev In tal caso è possibile utilizzare la risposta pubblicata da Nina. Si tratta di una buona scelta.
Mohammad Usman,

1
Questo può essere generalizzato usando la sintassi del parametro restante su([year, ...values]) => [year, values[n]]
JollyJoker l'

@JollyJoker - dovresti postarlo come risposta, è una soluzione generalizzata davvero carina e concisa
Filip Milovanović

@ FilipMilovanović Ho già fatto stackoverflow.com/a/60166014/7126740
JollyJoker

6

È possibile utilizzare Array.prototype.forEachper scorrere gli elementi dell'array originale, quindi creare i nuovi elementi e inserirli in nuovi array:

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

Produzione:

inserisci qui la descrizione dell'immagine


Generare dinamicamente i nostri array in modo che la soluzione funzioni indipendentemente dal numero di elementi degli array originali:

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

Produzione: inserisci qui la descrizione dell'immagine


Grazie mille per un'ottima risposta. Posso avere una domanda per il futuro? È possibile risolverlo non solo su 2 array ma anche su altri?
Dominik Lev,

1
È possibile generare dinamicamente gli array senza sapere in anticipo quanti elementi avranno gli array originali. Dai un'occhiata alla mia risposta modificata :)
Ismael Padilla,

4

Prima di tutto, all'inizio hai una serie di array. È possibile mapquesto array in due array diversi usando destructuringper ottenere ogni valore dai sottoarray in modo conciso:

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


4

Eseguire il ciclo attraverso l'array principale e restituire un nuovo array utilizzando valori di indice fissi per accedere ai valori di array figlio.

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)


3

È possibile utilizzare la funzione di riduzione come segue che scorre una sola volta:

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


Perché il CSS in questa risposta?
Joshua Fox,

1
@JoshuaFox solo per espandere l'altezza della console.
Ele

3

Ecco qui

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


2

Ho usato map per loop, due array per spingere i valori necessari.

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)


1

un'altra soluzione:

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


1

Per la soluzione generica, penso che la creazione di una matrice di indici per le colonne dei valori offra un modo semplice di mappare i dati completi sugli array desiderati.

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

ti dà una serie di indici, meno la colonna che era l'anno e

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

ti dà l'array che desideri per l'ennesima colonna del valore. Così:

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


0

Un'altra soluzione per array di input di lunghezza generica.

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


0

Utilizzare questa soluzione per creare qualsiasi combinazione generica dall'array multidimensionale esistente. Devi passare l'indice degli articoli da scegliere esplicitamente ed è questo che lo rende generico.

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.