1
votes

Script Google Apps: combiner des tableaux en cas de correspondance entre les deux tableaux

Contexte

J'ai deux tableaux (Array 1 et Array 2). Les deux partagent un type d'ID (colonne 2 du tableau 1 et colonne 0 du tableau 2). Je souhaite combiner les deux tableaux verticalement uniquement lorsqu'il y a une correspondance dans cet ID.

Tableaux de départ:

array1 = [[AB2C, Red, 113]
          [BE4F, Green,164]
          [AE3G, Blue, 143]];

array2 = [[143, FabricB2, W5]
          [189, FabricC9, W4]
          [113, FabricA3, W5]];

array3 = [];

array3.push(array1.map( function(e) { return e[2] == array2.map ( function (f) { return f[0] } ) }));

Tableau de fin souhaité

array3 = [[AB2C, Red, 113, FabricA3, W5]
          [AE3G, Blue, 143, FabricB2, W5]];

Méthodologie

Il me semble que le moyen le plus efficace de le faire serait de:

  1. Créez un tableau vide.
  2. Transférer les données du tableau 1 vers le tableau 3 si la colonne ID fait une correspondance avec celle du tableau 2.
  3. Transférer les données du tableau 2 vers le tableau 3 où la colonne ID correspond au tableau 3. Nous devons également ajouter uniquement les colonnes 1 et 2 du tableau 2 afin de ne pas dupliquer la colonne ID.

Ce que j'ai essayé

Pour l'étape 2, j'ai essayé de pousser le tableau 1 vers le tableau 3 avec un combo push et map comme ci-dessous, mais cela ne fonctionne pas correctement. Mon intention était de prendre chaque ligne du tableau 1, de l'exécuter à travers chaque ligne du tableau 2 pour vérifier une correspondance; s'il y a une correspondance, appuyez sur le tableau 3.

Pour l'étape 3, ma pensée était de prendre chaque ligne de la colonne 2 du tableau 3, de l'exécuter à travers chaque ligne de la colonne 0 du tableau 2, et en trouvant match, concattez-les au tableau 3. Je n'ai jamais dépassé l'équation de l'étape 2 pour y arriver.

J'apprécierais VRAIMENT votre aide!

array1 = [[AB2C, Red, 113]       <--Match
          [BE4F, Green,164]
          [AE3G, Blue, 143]];    <--Match

array2 = [[143, FabricB2, W5]    <--Match
          [189, FabricC9, W4]
          [113, FabricA3, W5]];  <--Match

1 commentaires

Citez "" les valeurs de votre tableau ou elles ne sont pas valides.


4 Réponses :


0
votes

Je pense que cela devrait faire l'affaire pour vous:

let array1 = [['AB2C', 'Red', 113], ['BE4F', 'Green',164], ['AE3G', 'Blue', 143]];

let array2 = [[143, 'FabricB2', 'W5'], [189, 'FabricC9', 'W4'], [113, 'FabricA3', 'W5']];

let array3 = []
array1.forEach(i => {
  let match = i[2]
  array2.forEach(j => {
    if(j[0] === match) {
      array3.push([...i, j[1], j[2]])
    }
  })
})

console.log(array3)

Lien Sandbox


1 commentaires

L'inconvénient est que vous ne pouvez pas casser le .forEach () , si une correspondance est trouvée. Cela conduit à une boucle inutile après avoir trouvé la correspondance. Une simple boucle for ici pourrait être meilleure.



1
votes

array1 = [
  ['AB2C', 'Red', 113],
  ['BE4F', 'Green', 164],
  ['AE3G', 'Blue', 143],
];

array2 = [
  [143, 'FabricB2', 'W5'],
  [189, 'FabricC9', 'W4'],
  [113, 'FabricA3', ' W5'],
];


const res = array1
  .map(x => array2
    .filter(y => y[0] === x[2])
    .map(y => [x[0], x[1], ...y]))
  .flatMap(x => x)

console.log(res)


1 commentaires

Merci. J'ai particulièrement aimé cette option car elle permettait d'augmenter le nombre de colonnes dans array2 sans avoir à les spécifier individuellement.



0
votes

Voici une approche alternative qui pourrait vous intéresser.

Maintenant que nous avons le runtime V8 dans Apps Script, vous pouvez utiliser une bibliothèque tierce comme AlaSQL pour effectuer des requêtes SQL complexes.

Il suffit de copier-coller la dernière version d'AlaSQL ( full ou minified ) dans son propre fichier de script dans votre projet Apps Script.

Ensuite, vous pouvez exécuter des requêtes comme celle-ci: p >

<script src="https://cdnjs.cloudflare.com/ajax/libs/alasql/0.5.5/alasql.min.js"></script>
const arr1 = [
  ['AB2C', 'Red', 113],
  ['BE4F', 'Green', 164],
  ['AE3G', 'Blue', 143],
].map( ([code, color, id]) => ({id, color, code}));

const arr2 = [
  [143, 'FabricB2', 'W5'],
  [189, 'FabricC9', 'W4'],
  [113, 'FabricA3', 'W5'],
].map( ([id, fabric, textile]) => ({id, fabric, textile}));

const query = `
    SELECT arr1.id, arr1.code, arr1.color, arr2.fabric, arr2.textile
    FROM ? AS arr1
    INNER JOIN ? AS arr2 ON arr1.id = arr2.id
`;

var res = alasql(
        query, 
        [arr1, arr2]
    ).map(
        ({id, code, color, fabric, textile}) => [code, color, id, fabric, textile]
    );

console.log(res);

J'ai pris quelques libertés avec vos tables de données en les convertissant d'un tableau de tableaux en un tableau d'objets et inversement en utilisant des affectations de déstructuration. Le vrai pouvoir de cette approche est qu'elle vous permet d'exploiter le SQL standard pour exécuter toutes sortes de requêtes complexes sur plusieurs ensembles de données.


0 commentaires

1
votes
  • Utilisez la carte pour créer une carte de array2.
  • Filtrer le tableau1 selon que Map a l'ID de ce tableau.
  • Le filtre étant une boucle, il est possible de modifier la ligne à l'intérieur du filtre
  • const array1 = [
      ['AB2C', 'Red', 113],
      ['BE4F', 'Green', 164],
      ['AE3G', 'Blue', 143],
    ];
    
    const array2 = [
      [143, 'FabricB2', 'W5'],
      [189, 'FabricC9', 'W4'],
      [113, 'FabricA3', ' W5'],
    ];
    
    const array2Map = new Map;
    array2.forEach(([row0, ...rest]) => array2Map.set(row0, rest));
    
    const out = array1.filter(row => array2Map.has(row[2]) && row.push(...array2Map.get(row[2])));
    console.info(out)

1 commentaires

Merci pour votre contribution cohérente à mes questions !!