Tengo una gran variedad de objetos. Cada objeto tiene las mismas propiedades. Intento crear una función para devolver una matriz de matrices donde cada matriz interna debe contener valores basados en los nombres de propiedad de los objetos.

Entrada:

input: [
    {
       test1: '10',
       test2: '15',
       test3: '14',
       test4: '22'
    },
    {
       test1: '4',
       test2: '1',
       test3: '45',
       test4: '2'
    },
    {
       test1: '5',
       test2: '16',
       test3: '7',
       test4: '0'
    }
]

Salida esperada: la matriz interna contiene solo elementos cuyas claves son las mismas. Por ejemplo, valores test1 en una matriz: [10, 4, 5]:

output: [[10, 4, 5], [15, 1, 16], [14, 45, 7], [22, 2, 0]]

Mi enfoque es usar array.entries () y el iterador. El resultado es incorrecto: los valores se almacenan en el orden incorrecto.

let output = [];
sort(input) {
    const results = [[], [], [], []];
    if (input.length > 0) {
      const iterator = input.entries();
      let item = iterator.next();
      while (!item.done) {
        const data = Object.values(item.value[1]);
        results.forEach((result, index) => {
          if (item.value[0] == index)
            result.push(parseFloat(data[index]));
        });
        item = iterator.next();
      }
    }
    output = results;
  }

¿Cómo lo hago funcionar?

1
kabugh 27 may. 2020 a las 18:51

5 respuestas

La mejor respuesta

Aquí hay una técnica, que solo usa el orden de las teclas del primer objeto para determinar el orden de salida final:

const restructure = (input = []) => 
  Object .keys (input [0] || {}) 
    .map (k => input .map (x => x [k]))

const input = [{test1: '10', test2: '15', test3: '14', test4: '22'}, {test1: '4', test2: '1', test3: '45', test4: '2'}, {test1: '5', test2: '16', test3: '7', test4: '0'}]

console .log (restructure (input))
.as-console-wrapper {min-height: 100% !important; top: 0}

Simplemente extraemos las claves compartidas del primer objeto y las usamos para determinar qué extraer de cada una de ellas.

4
Scott Sauyet 27 may. 2020 a las 16:07

Sería mucho más simple cuando utilizamos reduce.

var input=[ { test1: '10', test2: '15', test3: '14', test4: '22' }, { test1: '4', test2: '1', test3: '45', test4: '2' }, { test1: '5', test2: '16', test3: '7', test4: '0' }];

var result = Object.values(input.reduce((acc, elem)=>{
  Object.entries(elem).forEach(([k,v])=>{
    acc[k] = acc[k] || [];
    acc[k].push(v);
  })
  return acc;
},{}));

console.log(result)
0
gorak 27 may. 2020 a las 16:19

El uso de un bucle anidado puede proporcionarle el resultado esperado de la siguiente manera.

let input = [
    {
       test1: '10',
       test2: '15',
       test3: '14',
       test4: '22'
    },
    {
       test1: '4',
       test2: '1',
       test3: '45',
       test4: '2'
    },
    {
       test1: '5',
       test2: '16',
       test3: '7',
       test4: '0'
    }
];

const getValues = (data) => {
  // Get keys in the object
  let keys = Object.keys(data[0]);
  // Initialize the result with empty arrays
  let temp = [...Array(Object.keys(data[0] || {}).length)].map(x => []);

  for (let i=0; i<data.length; i++) {
    for (let j=0; j<keys.length; j++) {
      let str = keys[j];
      temp[j].push(data[i][str]);
    }
 }
 console.log(temp);
}

getValues(input);
0
Damien Asseya 27 may. 2020 a las 16:23

Interesante. Pero no tendría ese enfoque, preferiría usar mucho menos "cosas", así. No entiendo por qué la función se llama "sort", ¡no hay ningún tipo!

"use strict";

function sort(data)
{
  var stacks, stacknames;

  stacks = [];
  stacknames = {};

  data.forEach(item => {
    var k;

    for (k in item)
    {
      if (!(k in stacknames))
      {
        stacknames[k] = stacks.length; // map name to index
        stacks.push([]); // allocate new stack
      }

      stacks[stacknames[k]].push(parseFloat(item[k]));
    }
  });

  return stacks;
}

var input = [
    {
       test1: '10',
       test2: '15',
       test3: '14',
       test4: '22'
    },
    {
       test1: '4',
       test2: '1',
       test3: '45',
       test4: '2'
    },
    {
       test1: '5',
       test2: '16',
       test3: '7',
       test4: '0'
    }
];

var output = sort(input);

console.log(output);
0
pid 27 may. 2020 a las 16:13
let input = [{
    test1: '10',
    test2: '15',
    test3: '14',
    test4: '22'
  },
  {
    test1: '4',
    test2: '1',
    test3: '45',
    test4: '2'
  },
  {
    test1: '5',
    test2: '16',
    test3: '7',
    test4: '0'
  }
]

// initialize result array
let result = [...Array(Object.keys(input[0] || {}).length)].map(x => []);
// fill object
input.forEach(val => {
  // push each value into the according position in the result array.
  Object.values(val).forEach((val, i) => {
    result[i].push(val)
  });
});
console.log(result);
2
Paul 27 may. 2020 a las 16:11