1
votes

Le moyen le plus efficace de transformer des tableaux d'objets

Je veux transformer ce tableau d'objets en un autre tableau d'objets mais en sortie d'une manière différente. Quelle est la méthode la plus efficace et / ou la plus rapide (en termes de performances s'il y a une énorme quantité de tableaux)? Dois-je utiliser un pour ... on, lodash, filtrer ou réduire? merci

let array = {
 "opex":{
  "2017":90000, "2018":108500, "2019":153000
 },
 "netRevenue":{
  "2017":50000, "2018":55000, "2019":120000
 },
 "payroll":{
  "2017":60000, "2018":70000, "2019":100000
 },
 "rent":{
  "2017":20000, "2018":22500, "2019":25000
 },
 "marketing":{
  "2017":5000, "2018":10000, "2019":20000
 },
 "other":{
  "2017":5000, "2018":6000, "2019":8000
 }
}

à

let array = [
 {
   "years": "2017", "opex": 90000, "netRevenue": 50000, "payroll": 60000, "rent":20000, "marketing":5000, "other":5000
 },
 {
   "years": "2018", "opex": 108500, "netRevenue": 55000, "payroll": 70000, "rent":22500, "marketing":10000, "other":6000
 },
 {
   "years": "2019", "opex": 153000, "netRevenue": 120000, "payroll": 100000, "rent":25000, "marketing":20000, "other":8000
 },
]

MISE À JOUR Ajouté avec des guillemets doubles si nécessaire


5 commentaires

Qu'entendez-vous exactement par «transformer»? Il existe différentes méthodes de tableau et il serait utile de savoir quel type de sortie vous attendez :)


ce que vous attendez est un tableau à clé qui n'est pas possible êtes-vous sûr de vouloir un tableau ou un objet comme sortie finale ??


Utilisez ce que vous voulez et avec lequel vous vous sentez à l'aise. Si vous avez quelque chose qui fonctionne, testez votre projet avec un profileur. Et seulement si la transformation des tableaux est le goulot d'étranglement, commencez à l'optimiser.


Eh bien, je soupçonne qu'il a mélangé les crochets pour l'objet de sortie: [] au lieu de {} ...


son rien, c'est ce que j'essayais de souligner .. comme pour l'attendu son et tableau qui ne contient pas d'objet valide


4 Réponses :


1
votes

La sortie souhaitée n'est pas un tableau valide mais vous pouvez le faire avec un objet à la place

  1. vous passerez d'abord en boucle sur le tableau et
  2. obtenir la valeur de l'année
  3. puis récupérez toutes les clés de l'objet
  4. assurez-vous que la clé n'est pas "années" car vous ne le souhaitez pas dans votre résultat par spécification
  5. vérifier si cette clé existe dans l'objet resultObject
  6. sinon, créez un nouvel objet avec la clé des éléments
  7. si c'est le cas, ajoutez l'élément à la clé des objets

JSON.parse(resultObject) which will make sure all keys have quotation marks

Gardez à l'esprit que cela n'aura qu'une valeur par an si vous souhaitez à la place ajouter les valeurs que vous pourriez:

resultObject[key][year] = resultObject[key][year] + elm[key]

MODIFIER (basé sur OP update) Il n'y a pas non plus de raison d'ajouter des guillemets pour un objet javscript dans ce cas. si vous devez ultérieurement devenir un objet JSON, convertissez-le simplement avec:

let array = [{years: 2018, opex: 90000, netRevenue: 50000, payroll: 60000, rent:20000, marketing:5000, other:5000},{years: 2018, opex: 108500, netRevenue: 55000, payroll: 70000, rent:22500, marketing:10000, other:6000},{years: 2019, opex: 153000, netRevenue: 120000, payroll: 100000, rent:25000, marketing:20000, other:8000},]

const resultObject = {}

array.forEach(elm=>{
  const year = elm.years

  Object.keys(elm).forEach(key=>{
     if(key === 'years') return

     if(!resultObject[key]){
      resultObject[key] = {[year]:elm[key]}
     } else {
      resultObject[key][year] = elm[key]
     }
  })
})

console.log(resultObject)


1 commentaires

Édité avec une explication de l'objet javascript vs objet JSON



1
votes

Votre objet retourné ne sera probablement pas un tableau, mais un objet. opex , netRevenue , payroll et autres finiront par les clés de l'objet retourné.

Cela dit, dans ce Array.reduce () est un outil très utile.

let array = [
 {
   years: 2017, opex: 90000, netRevenue: 50000, payroll: 60000, rent:20000, marketing:5000, other:5000
 },
 {
   years: 2018, opex: 108500, netRevenue: 55000, payroll: 70000, rent:22500, marketing:10000, other:6000
 },
 {
   years: 2019, opex: 153000, netRevenue: 120000, payroll: 100000, rent:25000, marketing:20000, other:8000
 },
]

function turnArrayToDataPoints(arr){
  /****
   * This reduce will return an object, and each of the departments will be an
   *   array with elements that look like `2017:25000`.
   ****/
  const remappedArray = arr.reduce((returnObj, element)=>{
    // the years property is unique, so we'll pull it out.
    let thisYear = element.years;
    
    // Now, we can iterate over the properties for the current element in arr.
    //  if we have NOT created a property with this name on our return object,
    //  we want to create an empty array. Then, either way, we push a string on.
    for(let propName in element){
      if(propName !== 'years'){
        if(!returnObj.hasOwnProperty(propName))
          returnObj[propName] = {};
        returnObj[propName][thisYear] = element[propName];
      }
    }
    // And within our reduce, we need to remember to return our object.
    return returnObj;
  }, {}) //<-- this is the empty object we'll populate above.
  
  return remappedArray;
}

console.log(turnArrayToDataPoints(array));

Comme cela a été souligné, la suppression de la propriété 'years' est une mauvaise forme d'un point de vue fonctionnel. Modification du code pour vérifier simplement si la propriété donnée est à la place "années".


3 commentaires

vous retournez une chaîne plutôt que l'objet pour chaque valeur qui est ce que l'op a demandé (bien que vous ayez raison de dire que cela doit être un résultat obj)


De plus, votre utilisation de delete element.years modifie le tableau d'origine, ce qui est probablement une mauvaise pratique


C'est vrai, du moins d'un point de vue fonctionnel. Édité à nouveau. Merci!



1
votes

En supposant que tous les objets de votre tableau ont les mêmes propriétés, vous pouvez collecter les clés du premier objet et les utiliser pour parcourir tout le tableau:

let array = [ { years: 2017, opex: 90000, netRevenue: 50000, payroll: 60000, rent:20000, marketing:5000, other:5000 }, { years: 2018, opex: 108500, netRevenue: 55000, payroll: 70000, rent:22500, marketing:10000, other:6000 }, { years: 2019, opex: 153000, netRevenue: 120000, payroll: 100000, rent:25000, marketing:20000, other:8000 } ];

var keys=Object.keys(array[0]).slice(1);
var res={};
keys.forEach(k=>res[k]={});
array.forEach(c=>
  keys.forEach(k=>res[k][c.years]=c[k]));
console.log(res)


0 commentaires

1
votes

L'objectif est de minimiser le nombre d'itérations sur le même ensemble d'objets.

let array = [
 {
   "years": "2017", "opex": 90000, "netRevenue": 50000, "payroll": 60000, "rent":20000, "marketing":5000, "other":5000
 },
 {
   "years": "2018", "opex": 108500, "netRevenue": 55000, "payroll": 70000, "rent":22500, "marketing":10000, "other":6000
 },
 {
   "years": "2019", "opex": 153000, "netRevenue": 120000, "payroll": 100000, "rent":25000, "marketing":20000, "other":8000
 },
]

let output={};

array.forEach(obj=>{
  Object.keys(obj).filter(key=>key!=="years")
  .forEach(key=>{
    output[key] = output[key] || {};
    output[key][obj.years]=obj[key]
  })
})

console.log(output)


0 commentaires