8768 sujets

Développement web côté serveur, CMS

Bonjour... et bonne année à tous !

J'ai une fonction qui me renvoie un objet de ce type (et oui, toujours mon calendrier !) :
{
  p: {
    key: 'christmastide',
    name: 'Octave de la Nativité du Seigneur',
    color: [ 'white' ],
    priority: 9,
    subKey: 'octaveOfChristmas'
  },
  f: {
    key: 'christmas',
    name: 'Nativité du Seigneur',
    color: [ 'white' ],
    type: 1,
    priority: 2
  },
  m: {},
  key: 'christmas',
  name: 'Nativité du Seigneur',
  extra: '',
  fullName: 'Nativité du Seigneur',
  link: '',
  color: [ 'white', 'white' ],
  type: 'Solennité',
  priority: 2,
  date: '25/12/2020',
  weekday: 5
}

Question, comment gérer plusieurs valeurs pour une même propriété lorsque leur nombre n'est pas connu à l'avance ?

Comme vous pouvez le voir dans l'exemple j'anticipe certaines situations en créant à l'avance un tableau (ici pour les couleurs). Mais j'aurais besoin d'étendre cette possibilité pour pas mal de propriétés de l'objet. Y aurait-il une solution plus élégante ?

PS : cette question me semble agnostique pour ce qui est du langage utilisé, mais pour info je suis sous Node.js, le traitement de l'objet se fait donc en javascript.
Modifié par Olivier C (03 Jan 2021 - 17:55)
Modérateur
Bonjour,

J'ai du mal à voir le sens de la question.

Ce qui te gêne, c'est d'utiliser un tableau même dans le cas où il n'y a qu'une seule valeur ?

Amicalement,
Bonjour parsimonhi,

Ce qui me gène c'est de devoir prévoir le comportement en cas d’extension de l'application. Peut-être devrais-je faire quelque chose comme ceci ? :
// propriété "plus" :
{
  p: {},
  f: {
    key: 'mostHolyNameOfJesus',
    name: 'Saint Nom de Jésus,
    color: 'white',
    type: 4,
    priority: 12,
    plus: {
      key: 'genevieveOfParis',
      name: 'Sainte Geneviève, vierge',
      color: 'white',
      type: 4,
      priority: 12
    }
  },
  m: {}
}

// output d'origine (simplifié) :
{
  p: {},
  f: {
    key: 'mostHolyNameOfJesusOrGenevieveOfParis',
    name: 'Saint Nom de Jésus ou Sainte Geneviève, vierge',
    color: [ 'white' ],
    type: 4,
    priority: 12
  },
  m: {}
}

Modifié par Olivier C (03 Jan 2021 - 14:38)
Modérateur
Bonjour,

L'idée de la propriété "plus" est à éviter selon moi.

Il est peut-être temps pour toi d'utiliser des classes.

Exemple simplifié dans lequel on suppose que lors d'une version 1, on a des objets de classe 'holiday' ayant comme propriété key, name et color. Et on suppose que la valeur de la couleur est une chaine de caractères simple utilisée par ailleurs comme valeur de la propriété css color d'une balise <div> dans laquelle on affiche le nom d'une 'holiday'. L'idée est alors de passer par une méthode un peu particulière qu'on appelle un getter pour récupérer cette couleur et l'utiliser dans la suite du code.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="holiday_f"></div>
<script>
class holiday {
  constructor(key, name, color) {
    this.key = key;
    this.name = name;
    this.color = color;
  }
  get currentColor() {
    return this.color;
  }
  get currentName() {
    return this.name;
  }
}

let f = new holiday('mostHolyNameOfJesus', 'Saint Nom de Jésus', 'green');
document.getElementById("holiday_f").style.color=f.currentColor;
document.getElementById("holiday_f").innerHTML=f.currentName;
</script>
</body>
</html>


Un peu plus tard, tu décides dans une version 2 que la valeur de la propriété color des objets de classe 'holiday' est parfois une chaine de caractères, parfois un tableau, ce qui n'était pas prévu précédemment. Dans ce cas, il te suffit de réécrire le getter currentColor(), sans avoir besoin de toucher au reste du code. On va supposer ici qu'on renvoie soit la valeur de la propriété color si c'est une chaine de caractères, soit le 1er élément trouvé dans la valeur de la propriété color si c'est un tableau.

On obtient alors :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="holiday_f"></div>
<div id="holiday_g"></div>
<script>
class holiday {
  constructor(key, name, color) {
    this.key = key;
    this.name = name;
    this.color = color;
  }
  get currentColor() {
    if(Array.isArray(this.color)) return this.color[0];
    return this.color;
  }
  get currentName() {
    return this.name;
  }
}

let f = new holiday('mostHolyNameOfJesus', 'Saint Nom de Jésus', 'green');
document.getElementById("holiday_f").style.color=f.currentColor;
document.getElementById("holiday_f").innerHTML=f.currentName;
let g = new holiday('christmas', 'Nativité du Seigneur', ['red','blue']);
document.getElementById("holiday_g").style.color=g.currentColor;
document.getElementById("holiday_g").innerHTML=g.currentName;
</script>
</body>
</html>

Si tu n'as que 2 objets, c'est évidement très lourd. Mais si t'en as des centaines, accompagnés de nombreux traitements, ça peut avoir du sens.

De manière similaire, on peut utiliser des setters pour modifier les valeurs des propriétés des objets.

Ce n'est qu'une idée parmi d'autres.

Amicalement,
Modifié par parsimonhi (03 Jan 2021 - 20:10)
Meilleure solution
Ah ! Il est là le secret :
Array.isArray()

J'avais eu l'idée de tester le tableau avec cette méthode mais je ne savais pas si c'était la meilleure solution.

Quand aux classes, ça fait un moment que je leur tourne autour (depuis PHP que j'ai délaissé il y a quelque temps déjà) mais je n'ai jamais réussi à m'y mettre. Je pense que je manque de capacité d'abstraction avec le code, sans doute par manque de pratique, mais c'est sûr qu'il faudra que je m'y colle un jour.

Merci d'avoir pris le temps de me donner une réponse aussi complète. Bien souvent je ne mets pas en application dans la foulée une réponse pertinente qui élargie d'un coup mon champ de vision (comme celle que tu viens d'écrire). Puis, après un peu de temps je reviens voir, à tête reposée, un topic que j'avais ouvert et les réponses qui m'avaient posé question, et je code un petit prototype à partir de là.

Merci encore. Amicalement.