3
votes

Comment créer une chaîne conditionnelle basée sur deux variables sans un tas de if elses (JavaScript)

J'essaye de créer une chaîne personnalisée à montrer à l'utilisateur, qui est basée sur deux variables.

Voici l'exemple que j'essaye de construire:

let url1;
let url2;
if (containsData1) {
  url1 = "http://test";
}

if (containsData2) {
  url2 = "http://test2";
}

let finalString = '';
if (url1 && url2) {
  finalString = 'The url 1 is ' + url1 + ' and url 2 is ' + url2;
} else if (!url1 && url2) {
  finalString = 'There isnt data for url1. Url2 is ' + url2;
} else if (url1 && !url2) {
  finalString = 'The url 1 is ' + url1 + '. There isnt data for url2';
} else if (!url1 && !url2) {
  finalString = 'There isnt data for url1. There isnt data for url2';
}


0 commentaires

4 Réponses :


3
votes

Vous pouvez utiliser des instructions ternaires:

let url1;
let url2;
url1 = "http://test";
url2 = "http://test2";
let finalString = (url1 ? 'The url 1 is ' + url1 : 'There isnt data for url1.') +
  (url1 && url2 ? ' and t' : ' T') +
  (url2 ? 'he url 2 is ' + url2 : 'There isnt data for url2.');

console.log(finalString)


2 commentaires

Ouais je suppose que c'est ma seule option, je crois qu'il n'y a rien de plus chic que ça ... merci pour votre réponse!


Aucun problème. Si vous avez besoin de plus d'aide, n'hésitez pas à demander.



0
votes

1er - Utiliser les modèles de chaîne ES6

const urls = {
  url1: containsData1 ? "http://test" : null,
  url2: containsData2 ? "http://test" : null,
}

const assertData = name => urls[name] ? `${name} is ${urls[name]}` : `isnt data for ${name}`

let finalString = `${assertData('url1')}. ${assertData('url2')}`

2ème - unifier et extraire

let url1;
let url2;
if (containsData1) {
  url1 = "http://test";
}

if (containsData2) {
  url2 = "http://test2";
}

let finalString = '';
if (url1 && url2) {
  finalString = `The url 1 is ${ url1 } and url 2 is ${ url2 }`;
} else if (!url1 && url2) {
  finalString = `There isnt data for url1. Url2 is ${ url2 }`;
} else if (url1 && !url2) {
  finalString = `The url 1 is ${ url1 }. There isnt data for url2`;
} else if (!url1 && !url2) {
  finalString = 'There isnt data for url1. There isnt data for url2';
}


0 commentaires

0
votes

Je suis sûr que nous pourrions être encore plus précis avec les instructions ternaires:

let url1 = containsData1;
let url2 = containsData2;

let finalString = url1 ? `The url 1 is ${url1}` : 'There is no data for url 1';

if (url1 && url2) {finalString += ` and url 2 is ${url2}.`}
if (!url2) {finalString += '. There is no data for url2.'}


2 commentaires

contientData1 || null n'est pas nécessaire si vous utilisez un opérateur conditionnel ou un if . Une valeur falsey est toujours une valeur falsey pour tous, attribuer null ne sert à rien ici.


Vous avez raison, merci pour cela. Avoir mis à jour le code ci-dessus. Les valeurs falsey satisferont toujours les déclarations ternaires / if.



0
votes

Il est préférable de traiter cela comme deux chaînes conditionnelles différentes, puis de les joindre ensemble:

function(urls) {
  let finalString = urls
    .map((url, i) => makeSubMessage(url, "Url" + (i + 1)))
    .map(subMessage => `<li>${subMessage}</li>`)
    .join("<br/>")

  return `<ul>${finalString}</ul>`;
}

Cela vous permet de raisonner sur la chaîne résultante d'une manière plus simple que de considérer chaque cas possible immediatement. Avec seulement deux variables, vous avez 4 résultats possibles, avec 4 vous en auriez 16 .

Séparer chaque variable signifie que vous n'avez pas besoin de vous soucier des autres possibilités lorsque vous générez chaque sous-chaîne.

Vous pouvez encore simplifier la réflexion en utilisant des modèles. Dans ce cas, vous pouvez séparer la logique de génération de chaîne ailleurs pour vous concentrer sur différentes choses dans différents domaines

  • déterminer ce que chaque message doit être
  • trouver comment les afficher

Par exemple, vous voudrez peut-être normaliser les messages et avoir quelque chose comme:

function(urls) {
  let finalString = urls
    .map((url, i) => makeSubMessage(url, "Url" + (i + 1)))
    .join("\n")

  return finalString;
}

Ce qui vous permettra d'échanger plus facilement le format des messages est sans avoir à toucher à la façon dont ils sont ensuite présentés.

Lorsque vous les présentez, vous voudrez peut-être avoir chaque message sur une ligne distincte, plutôt qu'une simple chaîne, de sorte que le résultat ne doit pas dépendre de ce les sous-messages sont:

function(urls) {
  let finalString = "";
  for (let i = 0; i < urls.length; i++) {
    let subMessage = makeSubMessage(urls[i], "Url" + (i + 1));
    finalString += subMessage;
    finalString += "\n"
  }

  return finalString;
}

Ou vous pouvez modifier entièrement cette implémentation:

function makeSubMessage(url, name) {
  if (url) {
    return `The $[name} is ${url}`;
  } else {
    return `No data for ${name}`;
  }
}
/* ... */
let string1 = makeSubMessage(url1, "Url1");

ou changer pour les afficher sous forme de puces HTML , peut-être:

let string1;
if (url1) {
  string1 = 'The url 1 is ' + url1 + '.';
} else {
  string1 = 'There isnt data for url1.';
}

let string2;
if (url2) {
   string2 = 'Url2 is ' + url2;
} else {
  string2 = 'There isnt data for url2';
}

let finalString = string1 + string2;

Ou autre chose. Le fait est que les préoccupations sont désormais séparées.


0 commentaires