1
votes

Utilisez un tableau d'objets pour générer un nouveau tableau de manière dynamique

J'ai un formulaire de produit auquel j'aimerais que les utilisateurs ajoutent des variantes de ce produit. Mon objet pour les paramètres principaux

{Size: "60cm", Color: "White", Image: "img.png"},
{Size: "60cm", Color: "Black", Image: "img.png"},
{Size: "60cm", Color: "Red", Image: "img.png"},
{Size: "80cm", Color: "White", Image: "img.png"},
{Size: "80cm", Color: "Black", Image: "img.png"},
{Size: "80cm", Color: "Red", Image: "img.png"},
{Size: "120cm", Color: "White", Image: "img.png"},
{Size: "120cm", Color: "Black", Image: "img.png"},
{Size: "120cm", Color: "Red", Image: "img.png"},

Donc, pour chaque option, j'ai besoin d'une variante avec chaque titre et sa valeur - qui sera régénérée et renvoyée aux .settings.variants ci-dessus. p>

J'ai créé un Stackblitz https://stackblitz.com/edit/angular-pi27mf

Dans cette méthode, j'ai besoin de générer de nouvelles variantes [], pour l'instant je ne comprends que comment générer quelque chose comme

{Size: "60cm", Color: "White", Image: "img.png"},
{Size: "60cm", Color: "Black", Image: "img.png"},
{Size: "60cm", Color: "Red", Image: "img.png"},

Par juste en boucle sur l'une des options .. mais comment puis-je parcourir toutes les options et créer une nouvelle variante pour chaque valeur possible?

Le modèle que j'aurais besoin de réaliser serait celui-ci

{
  title: 'Bike',
  settings: {
    options: [
      {
        title: 'Size',
        values: ['60cm', '80cm', '120cm']
      },
      {
        title: 'Color',
        values: ['White', 'Black', 'Red']
      }
    ],
    variants: []
  }
};

En gardant à l'esprit que la Taille et la Couleur sont dynamiques et peuvent être modifiées par l'utilisateur, la fonction ne peut donc pas dépendre de cela quantité / type d'options.

Je suis sûr qu'il y a des calculs de tableau à faire mais si quelqu'un pouvait me diriger dans la bonne direction ou recréer un stackblitz pour moi, ce serait une aide énorme.


0 commentaires

3 Réponses :


0
votes

Essayez ceci:

  generateVariants() {
    const options = [...this._form.settings.options];
    const sizeOptions = options[0].values;
    const colorOptions = options[1].values;
    const regeneratedVariants = [];
    for(let i=0;i< sizeOptions.length;i++) {
      for(let j=0;j< colorOptions.length;j++) {
        regeneratedVariants.push({
          Size: sizeOptions[i],
          Color: colorOptions[i],
          Image: "img.png"
        })
      }
    }
    console.log(regeneratedVariants);
  }

cela produira un tableau avec toutes les variantes possibles avec des tailles et des couleurs.


2 commentaires

Désolé, j'aurais dû mieux expliquer, mais la taille et la couleur seraient dynamiques, donc le modèle publié peut différer de ce que l'utilisateur saisit réellement.


Vous pouvez toujours utiliser cette logique pour générer des variantes, il vous suffit de trouver un moyen d'obtenir la taille et la couleur ou toute autre option.



1
votes

Vous pouvez créer un tableau de title et un tableau 2D de valeurs tableau en utilisant map . Créez ensuite un produit cartésien de toutes les valeurs . Ensuite, parcourez toutes les combinaisons et créez des objets en utilisant réduire . Utilisez {Image: "img.png"} comme paramètre initialValue . Cela fonctionnera pour n'importe quel nombre d'objets dans options array

const input = { title: 'Bike', settings: { options: [{ title: 'Size', values: ['60cm', '80cm', '120cm'] }, { title: 'Color', values: ['White', 'Black', 'Red'] }], variants: [] } }

const { options } = input.settings,
      titles = options.map(o => o.title),
      values = options.map(o => o.values),
      defaultObject = { Image: "img.png" }

// https://stackoverflow.com/a/57597533/3082296
const combos = values.reduce((acc, curr, i) =>
  acc.flatMap(c => curr.map(n => [].concat(c, n)))
)

const createObject = values =>
  titles.reduce((acc, k, i) => {
    acc[k] = values[i];
    return acc
  }, defaultObject)

const output = combos.map(createObject)

console.log(...output)


2 commentaires

De quoi ai-je besoin pour importer flatMap? La propriété 'flatMap' n'existe pas sur le type 'string []'.


Le fichier de déclaration Typescript ( .d.ts ) n'a pas Array.prototype.flatMap . Ainsi, le compilateur se plaint que flatMap n'est pas une extension de tableau Typecript flatMap, flat, flatten n'existe pas sur le type tout []



1
votes

Vous pouvez prendre les clés et les valeurs à partir de données, générer le produit cartésien à partir de valeurs et créer des paires clé / valeur comme résultat.

.as-console-wrapper { max-height: 100% !important; top: 0; }
var data = { title: 'Bike', settings: { options: [{ title: 'Size', values: ['60cm', '80cm', '120cm'] }, { title: 'Color', values: ['White', 'Black', 'Red'] }], variants: [] } },
    keys = data.settings.options.map(({ title }) => title).concat('Image'),
    values = data.settings.options.map(({ values }) => values).concat([['img.png']]),
    cartesian = values
        .reduce((a, b) => a.reduce((r, v) => r.concat(b.map(w => [].concat(v, w))), []))
        .map(a => Object.assign({ title: a.slice(0, -1).join('/') }, ...keys.map((k, i) => ({ [k]: a[i] }))));

console.log(cartesian);


2 commentaires

@Jayden change Object.assign (... keys.map ((k, i) en Object.assign ({}, ... keys.map ((k, i) < / code>


Sauriez-vous concaténer une variable de titre qui dans la valeur contient toutes les variantes, produisant {Size: '60cm', Color: 'White', Title: '60cm / White', Img: ''} ?