0
votes

Extraire les données du tableau dans son propre tableau

J'ai les données suivantes dans un tableau.

const payload = {}

this.tempAttachments.forEach(function (attachment, index) {
  payload[index] = {
    id: attachment._id
  }
})

Il y a deux éléments qui m'intéressent, et c'est le tableau _id et headers. J'essaie de me retrouver avec quelque chose comme ça

Array
(
  [0] => Array
  (
     [id] => 12345-678910
     [optionOne] => 0
     [optionTwo] => 2
     [optionThree] => 5
  )
  [1] => Array
  (
     [id] => 9999-2222
     [optionOne] => 0
  )
)

Donc, essentiellement, l'id et l'index des trois options car ils se rapportent à leur colonne dans un fichier. Le problème est qu'un fichier peut avoir un maximum de trois options (en utilisant les noms ci-dessus) cependant, ils peuvent n'en avoir qu'une ou deux.

J'ai donc commencé comme ça

tempAttachments:Array[2]
  0:Object
    _id:"12345-678910"
    bytes:412051
    file:File
    size:411532
    title:"someFile.csv"
    headers: Array[3]
        0: optionOne
        1: undefined
        2: optionTwo
        3: undefined
        4: undefined
        5: optionThree
    type:"file"
    fileType:"typeOne"
  1:Object
    _id:"9999-2222"
    bytes:12345
    file:File
    size:23456
    title:"anotherFile.csv"
    headers: Array[3]
        0: optionOne
    type:"file"
    fileType:"typeTwo"

Ce dont je ne suis pas sûr, c'est de savoir comment mapper les index des options, avec la clé définie comme nom, si elles existent. Quelle serait la meilleure façon d'y parvenir?

Merci


4 commentaires

utilisez une approche basée sur carte .


Qu'est-ce que optionOne , optionTwo , ... dans le tableau headers ? est-ce un type? peut-il en quelque sorte être traité comme une chaîne / transformé en une chaîne pour la partie de sortie attendue?


Ce ne sont que des cordes


Veuillez publier vos données au format JSON afin que nous puissions les utiliser facilement dans les tests


3 Réponses :


1
votes

Quelque chose comme ceci:

const tempAttachments = [{
    _id: "12345-678910",
    bytes: 412051,
    file: 'File',
    size: 411532,
    title: "someFile.csv",
    headers: [
        'optionOne',
        undefined,
        'optionTwo',
        undefined,
        undefined,
        'optionThree'
    ],
    type: "file",
    fileType: "typeOne"
}, {
    _id: "9999-2222",
    bytes: 12345,
    file: 'File',
    size: 23456,
    title: "anotherFile.csv",
    headers: [
        'optionOne',
        'optionTwo',
        'optionThree'
    ],
    type: "file",
    fileType: "typeTwo",
}];

const output = tempAttachments.reduce((akku, item) => {
    let akkuItem = {
        id: item._id,
    };
    item.headers.forEach((value, index) => {
        if(typeof value !== 'undefined') {
            akkuItem[value] = index;
        }
    });
    akku.push(akkuItem);
    return akku;
}, []);
console.log(output);


2 commentaires

item.headers est un tableau. Il n'est pas nécessaire de le traiter avec Object.entries ... item.headers.forEach le fera déjà. Par contre, il était préférable d'utiliser réduire pour les structures dont on ne souhaite collecter que certains éléments (donc réduire au lieu de forEach ). Encore une fois, map au lieu de reduction pour la structure externe était le choix préférable car on veut traiter / mapper chaque type de pièce jointe .


Vous avez raison, l'en-tête n'est pas un objet .. J'ai changé le code :) Merci.



2
votes

Ceci est un environnement / paramètre pour une approche combinée classique de map (ici: créez un nouveau type à partir de chaque type de pièce jointe ) et reduction (ici: créer / collecter de nouvelles données d'option uniquement pour l'option header / valide items) ...

.as-console-wrapper { min-height: 100%!important; top: 0; }
const tempAttachments = [{
  _id: "12345-678910",
  bytes: 412051,
  file: "File",
  size: 411532,
  title: "someFile.csv",
  headers: [
    "optionOne",
    undefined,
    "optionTwo",
    undefined,
    undefined,
    "optionThree"
  ],
  type:"file",
  fileType:"typeOne"
}, {
  _id: "9999-2222",
  bytes: 12345,
  file: "File",
  size: 23456,
  title: "anotherFile.csv",
  headers: [
    "optionOne"
  ],
  type: "file",
  fileType: "typeTwo"
}];


function collectValidOptionData(collector, optionItem, idx) {
  // if (optionItem != null) {
  //  collector[String(optionItem)] = idx
  // }
  if (typeof optionItem === 'string') {
    collector[optionItem] = idx;
  }
  return collector;
}

function createOptionTypeFromAttachment(attachmentType) {
  return attachmentType.headers.reduce(collectValidOptionData, {
    id: attachmentType._id
  });
}


console.log(
  'tempAttachments.map(createOptionTypeFromAttachment) : ',
  tempAttachments.map(createOptionTypeFromAttachment)
);


0 commentaires

2
votes

Une façon simple de le faire, consiste à utiliser la méthode Array.map , elle crée un nouveau tableau à partir d'un autre.

(Plus d'infos: https://developer.mozilla.org/en-US/docs/Web/JavaScript/ Reference / Global_Objects / Array / map )

Le code ci-dessous convertira les tempAttachments dans le nouveau format, où est basé dans cette structure:

XXX

Il n'ajoutera que les options qui ont une valeur, en ignorant les options non définies .

Solution:

const payload = tempAttachments.map(attachment => {
  const newAttachment = {
    id: attachment._id,
  }

  attachment.headers.forEach((option, index) => {
    if (option) {
      newAttachment[option] = index;
    }
  })

  return newAttachment;
})


2 commentaires

Je pense que false et 0 .. et d'autres valeurs fausses ne seront pas ajoutées.


Oui, toutes les valeurs fausses seront ignorées, y compris 0, false, chaînes vides, indéfinies, etc. J'ai dit spécifiquement indéfini car dans ce cas, seules les chaînes et undefined sont dans le tableau. C'est seulement pour faciliter la compréhension et ne pas le submerger d'informations.