IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

group by et concat dans tableau JS


Sujet :

JavaScript

  1. #1
    Membre habitué
    Homme Profil pro
    consultant environnement et développement d'applications de base de données
    Inscrit en
    Janvier 2006
    Messages
    336
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : consultant environnement et développement d'applications de base de données
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Janvier 2006
    Messages : 336
    Points : 166
    Points
    166
    Par défaut group by et concat dans tableau JS
    Bonjour,
    Je m'arrache les cheveux alors j'en appel à la communauté JS...
    J'ai un tableau associatif JS de ce type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    0: {famille: "produitIlot", code: "ECART_DISTANCE_EAU", prod_id: 1, prod_lib: "PLEDGE", ilot_key: "2185", …}
     
    1: {famille: "produitIlot", code: "ECART_DISTANCE_RIVERAIN", prod_id: 1, prod_lib: "PLEDGE", ilot_key: "2185", …}
     
    2: {famille: "dates", code: "DATE_ABSENT", prod_id: null, prod_lib: null, ilot_key: null, …}
     
    3: {famille: "dates", code: "DATE_ABSENT", prod_id: null, prod_lib: null, ilot_key: null, …}
     
    4: {famille: "produitIlot", code: "DEPASSEMENT_NB_APPLICATION", prod_id: 1, prod_lib: "PLEDGE", ilot_key: "2169", …}
     
    5: {famille: "produitIlot", code: "DEPASSEMENT_NB_APPLICATION", prod_id: 1, prod_lib: "PLEDGE", ilot_key: "2172", …}
     
    6: {famille: "produitIlot", code: "DEPASSEMENT_NB_APPLICATION", prod_id: 1, prod_lib: "PLEDGE", ilot_key: "2170", …}
     
    7: {famille: "produitIlot", code: "DEPASSEMENT_NB_APPLICATION", prod_id: 1, prod_lib: "PLEDGE", ilot_key: "2131", …}
     
    8: {famille: "melange", code: "PROD_MELANGE_INTERDIT", prod_id: 2, prod_lib: "", ilot_key: null, …}
     
    9: {famille: "dates", code: "DATE_ABSENT", prod_id: null, prod_lib: null, ilot_key: null, …}
     
    10: {famille: "dates", code: "DATE_ABSENT", prod_id: null, prod_lib: null, ilot_key: null, …}
     
    11: {famille: "melange", code: "PROD_MELANGE_INTERDIT", prod_id: 2, prod_lib: "", ilot_key: null, …}
     
    12: {famille: "dates", code: "DATE_ABSENT", prod_id: null, prod_lib: null, ilot_key: null, …}
     
    13: {famille: "dates", code: "DATE_ABSENT", prod_id: null, prod_lib: null, ilot_key: null, …}
    je cherche à :
    - supprimer les lignes en doublon tout d'abord...
    - générer un tableau groupé par prod_id puis code avec concaténation des ilot_key... ce qui donnerait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        tab_nc_prod[1] = [ {code:"ECART_DISTANCE_EAU",ilots:"2185"},{code:"ECART_DISTANCE_RIVERAIN",ilots:"2185"},{code:"DEPASSEMENT_NB_APPLICATION",ilots:"2169,2172,2170,2131"} ]
        tab_nc_prod[2] = [ {code:"PROD_MELANGE_INTERDIT",ilots:""} ]
    - un autre tableau groupé par ilot_key puis code mais avec concaténation des prod_id et prod_lib cette fois-ci...
    j'arrive à grouper à un niveau sur prod_id ou ilot_key avec reduce mais je n'arrive pas à faire le second niveau de regroupement avec concaténation de certaines propriétés.
    merci de votre aide

    guen

  2. #2
    Expert éminent sénior
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 409
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 409
    Points : 15 778
    Points
    15 778
    Par défaut
    vous pouvez parcourir la liste avec "forEach" comme cela :
    https://developer.mozilla.org/fr/doc.../Array/forEach

  3. #3
    Membre habitué
    Homme Profil pro
    consultant environnement et développement d'applications de base de données
    Inscrit en
    Janvier 2006
    Messages
    336
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : consultant environnement et développement d'applications de base de données
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Janvier 2006
    Messages : 336
    Points : 166
    Points
    166
    Par défaut
    parcourir certes mais comment je fais les regroupements et concaténations ? merci de votre aide.

  4. #4
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 446
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 446
    Points : 4 959
    Points
    4 959
    Par défaut
    Bonjour,

    J'ai fais un test vite fait pour arriver au résultat souhaité :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
       let obj = [] ;
       Array
      .from(new Set(tab_nc_prod.map(JSON.stringify).map(JSON.parse)))
      .map((value,index,self) => {
        !obj[value.prod_id]&&value.prod_id!=null ? obj[value.prod_id] = [] : '';
    	if(obj[value.prod_id])
    	self
    	.map((v) => {
    		if(v.code==value.code&&v.prod_id==value.prod_id){
    		let index=obj[value.prod_id].map(item=>{ return item.code;}).indexOf(v.code);
    		if(index>-1){
    			if(obj[value.prod_id][index].ilots!=null){
    				if(obj[value.prod_id][index].ilots.indexOf(value.ilot_key)==-1)
    					obj[value.prod_id][index].ilots+= ',' + value.ilot_key;
    			}
    			else{
    				obj[value.prod_id][index].ilots=value.ilot_key;
    			}
    		}
    		else{
    			  obj[value.prod_id]
    			  .push({
    				'code':value.code,
    				"ilots":value.ilots != null 
    					? value['ilots'] + ',' + value.ilot_key 
    					: value.ilot_key
    			  });
    		  }
    		}
    	});
     });
    //affichage
    console.log(obj);
    Résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    1: Array(3)
       0: {code: "ECART_DISTANCE_EAU", ilots: "2185"}
       1: {code: "ECART_DISTANCE_RIVERAIN", ilots: "2185"}
       2: {code: "DEPASSEMENT_NB_APPLICATION", ilots: "2169,2172,2170,2131"}
    2: Array(1)
      0: {code: "PROD_MELANGE_INTERDIT", ilots: null}
    Le principe est le même pour les autres propriétés, tu peux même créer une fonction avec des paramètres pour préciser les propriétés à regrouper.

  5. #5
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    Pour commencer il faut définir la structure qu'on veut obtenir.

    Ensuite on définit le plus simplement possible ce que veut dire regrouper sur une valeur de propriété. En entrée, on a une même valeur de code avec différentes valeurs qu'on veut regrouper par cette valeur de code. Ce qui veut dire qu'on va avoir une structure telle qu'une propriété unique "code" va avoir une valeur qui est le regroupement des différentes valeur.

    Par exemple, si on veut les produits d'id null dans le résultat, on utilisera un tableau associatif dont les clefs sont des prod_id et les valeurs des tableaux associatifs, dont les clefs sont la propriété de regroupement, donc le code.

    Ensuite, on parcourt les entrées du tableau associatif en entrée, avec un foreach par exemple comme indiqué par @Mathieu.

    Ensuite on définit comment pour chaque code, de chaque valeur d'entrée, on établit comment obtenir la valeur finale, une concaténation des clefs de lots.
    Le traitement des ilots null va conditionner les code final (si on les intégrer dans le résultats, ou pas).
    Il faut également définir comment la concaténation va être faite. Par exemple, on décide de séparer les clefs de lots par des virgules, avec une espace après par exemple, pour la lisibilité.

    Donc si on part du principe qu'on veut les prod_id null mais pas les clefs de lots null.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    var input =  {0: {famille: "produitIlot", code: "ECART_DISTANCE_EAU", prod_id: 1, prod_lib: "PLEDGE", ilot_key: "2185"},
    1: {famille: "produitIlot", code: "ECART_DISTANCE_RIVERAIN", prod_id: 1, prod_lib: "PLEDGE", ilot_key: "2185"},
    2: {famille: "dates", code: "DATE_ABSENT", prod_id: null, prod_lib: null, ilot_key: null},
    3: {famille: "dates", code: "DATE_ABSENT", prod_id: null, prod_lib: null, ilot_key: null},
    4: {famille: "produitIlot", code: "DEPASSEMENT_NB_APPLICATION", prod_id: 1, prod_lib: "PLEDGE", ilot_key: "2169"},
    5: {famille: "produitIlot", code: "DEPASSEMENT_NB_APPLICATION", prod_id: 1, prod_lib: "PLEDGE", ilot_key: "2172"},
    6: {famille: "produitIlot", code: "DEPASSEMENT_NB_APPLICATION", prod_id: 1, prod_lib: "PLEDGE", ilot_key: "2170"},
    7: {famille: "produitIlot", code: "DEPASSEMENT_NB_APPLICATION", prod_id: 1, prod_lib: "PLEDGE", ilot_key: "2131"},
    8: {famille: "melange", code: "PROD_MELANGE_INTERDIT", prod_id: 2, prod_lib: "", ilot_key: null},
    9: {famille: "dates", code: "DATE_ABSENT", prod_id: null, prod_lib: null, ilot_key: null}, 
    10: {famille: "dates", code: "DATE_ABSENT", prod_id: null, prod_lib: null, ilot_key: null},
    11: {famille: "melange", code: "PROD_MELANGE_INTERDIT", prod_id: 2, prod_lib: "", ilot_key: null},
    12: {famille: "dates", code: "DATE_ABSENT", prod_id: null, prod_lib: null, ilot_key: null},
    13: {famille: "dates", code: "DATE_ABSENT", prod_id: null, prod_lib: null, ilot_key: null}
    };
     
    var output= {};
     
    for (const [key, value] of Object.entries(input)) { // on parcourt les entrées du tableau associatif
      var prod_id = (value.prod_id===null?"null":value.prod_id); // on prends le produit correspondant dans le résultat
     
      if ( typeof output[prod_id] === 'undefined' ) // si ce produit n'était pas déjà présent...
          output[prod_id] = {}; // ... on l'initialise
     
      var prod = output[prod_id]; // on travaille ensuite sur le produit
     
      if ( typeof prod[value.code]  === 'undefined' ) // si il n'existe pas encore de ilots pour le code de l'entrée courante, on l'initialise
           prod[value.code] = null; 
     
     
      if ( prod[value.code] === null ) // si la "liste" de lots est null...
        prod[value.code] = value.ilot_key; //  ... alors la nouvelle liste est le lot courant (il peut être null mais par coïncidence, la liste sera null aussi)
      else if ( value.ilot_key !== null ) { // si le produit courant a un ilot
        if ( prod[value.code] !== null ) // si on a déjà une concaténation de key de ilots, alors on ajoute un séparateur
           prod[value.code] += ', '; 
        prod[value.code] += value.ilot_key;
      }
     
    }
     
    console.log(output);


    Le résultat :
    Code json : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    {
      1: {
        DEPASSEMENT_NB_APPLICATION: "2169, 2172, 2170, 2131",
        ECART_DISTANCE_EAU: "2185",
        ECART_DISTANCE_RIVERAIN: "2185"
      },
      2: {
        PROD_MELANGE_INTERDIT: null
      },
      null: {
        DATE_ABSENT: null
      }
    }

    Je suis parti du principe qu'un ilot ne peut se répéter entre code, ou que ça ne gêne pas qu'il se répète dans la concaténation. Dans le cas contraitre, il serait plus simple d'utiliser un tableau pour stocker les codes (avec un test de Array.includes() pour éviter de stocker plusieurs fois le même ilot) et faire un Array.join() à la fin, pour finaliser le résultat sous forme de concaténation.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
     
    var input =  {0: {famille: "produitIlot", code: "ECART_DISTANCE_EAU", prod_id: 1, prod_lib: "PLEDGE", ilot_key: "2185"},
    1: {famille: "produitIlot", code: "ECART_DISTANCE_RIVERAIN", prod_id: 1, prod_lib: "PLEDGE", ilot_key: "2185"},
    2: {famille: "dates", code: "DATE_ABSENT", prod_id: null, prod_lib: null, ilot_key: null},
    3: {famille: "dates", code: "DATE_ABSENT", prod_id: null, prod_lib: null, ilot_key: null},
    4: {famille: "produitIlot", code: "DEPASSEMENT_NB_APPLICATION", prod_id: 1, prod_lib: "PLEDGE", ilot_key: "2169"},
    5: {famille: "produitIlot", code: "DEPASSEMENT_NB_APPLICATION", prod_id: 1, prod_lib: "PLEDGE", ilot_key: "2172"},
    6: {famille: "produitIlot", code: "DEPASSEMENT_NB_APPLICATION", prod_id: 1, prod_lib: "PLEDGE", ilot_key: "2170"},
    7: {famille: "produitIlot", code: "DEPASSEMENT_NB_APPLICATION", prod_id: 1, prod_lib: "PLEDGE", ilot_key: "2131"},
    8: {famille: "melange", code: "PROD_MELANGE_INTERDIT", prod_id: 2, prod_lib: "", ilot_key: null},
    9: {famille: "dates", code: "DATE_ABSENT", prod_id: null, prod_lib: null, ilot_key: null}, 
    10: {famille: "dates", code: "DATE_ABSENT", prod_id: null, prod_lib: null, ilot_key: null},
    11: {famille: "melange", code: "PROD_MELANGE_INTERDIT", prod_id: 2, prod_lib: "", ilot_key: null},
    12: {famille: "dates", code: "DATE_ABSENT", prod_id: null, prod_lib: null, ilot_key: null},
    13: {famille: "dates", code: "DATE_ABSENT", prod_id: null, prod_lib: null, ilot_key: null}
    };
     
    var output= {};
     
    for (const [key, value] of Object.entries(input)) {
      var prod_id = (value.prod_id===null?"null":value.prod_id);
     
      if ( typeof output[prod_id] === 'undefined' ) 
          output[prod_id] = {};
      var prod = output[prod_id];
     
      if ( typeof prod[value.code]  === 'undefined' ) // si on a pas déjà un tableau intermédiaire de stockage des clefs pour ce code...
           prod[value.code] = []; // on initialise ce tableau 
     
      if ( value.ilot_key !== null && !prod[value.code].includes(value.ilot_key) ) // si la clef de lot n'est pas null, et qu'elle n'est pas déjà dans le tableau
           prod[value.code].push(value.ilot_key); // on la stocke dans le tableau
     
    }
     
    // on transforme le résultat pour avoir une concaténation
    for (const [key, value] of Object.entries(output)) { // on parcourt les entrées du résultat 
      for (const [code, prod_code_value] of Object.entries(value))   { // on parcourt les codes pour chaque entrée, soit des tableaux
         if ( prod_code_value.length===0 ) { // si le tableau est vide
            value[code] = null; // ou chaîne vide si on veut
         }
         else {
            value[code] = prod_code_value.join(', ');
         }
      }
    }
     
    console.log(output);


    La structure résultat est différente de celle que tu cherches à obtenir, mais le raisonnement de base (le regroupement) est le même. Je te laisse donc adapter le code pour gérer la structure que tu cherches à obtenir. La différence essentielle étant qu'au lieu d'avoir un objet avec des clefs qui sont directement les codes, tu as un tableau avec des objets avec une propriété code. un Array.find suffit à modifier légèrement le code pour gérer cette différence.

    L'étape suivante, pour faire un "group by", un peu plus complexe pour un débutant peut-être, est de regarder la fonction Array.reduce().

  6. #6
    Membre habitué
    Homme Profil pro
    consultant environnement et développement d'applications de base de données
    Inscrit en
    Janvier 2006
    Messages
    336
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : consultant environnement et développement d'applications de base de données
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Janvier 2006
    Messages : 336
    Points : 166
    Points
    166
    Par défaut
    merci à vous deux pour vos réponses bien développées ! cela va me permettre de trouver la solution j'en suis sûr.

Discussions similaires

  1. Réponses: 5
    Dernier message: 31/03/2017, 02h17
  2. Groupe de lignes dans tableau
    Par AnkyFive dans le forum Développement de jobs
    Réponses: 12
    Dernier message: 17/02/2016, 13h22
  3. Groupe de controles différents dans un tableau
    Par jacko842 dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 11/08/2009, 20h07
  4. Ne pas toujours afficher un groupe dans tableau croisé
    Par leloup84 dans le forum SAP Crystal Reports
    Réponses: 6
    Dernier message: 15/04/2008, 13h04
  5. GROUP BY et HAVING dans un UPDATE
    Par MashiMaro dans le forum Langage SQL
    Réponses: 3
    Dernier message: 26/08/2003, 08h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo