Как создать условную строку, основанную на двух переменных, без связки if elses (JavaScript) - PullRequest
3 голосов
/ 30 мая 2019

Я пытаюсь создать пользовательскую строку для показа пользователю, основанную на двух переменных.

Вот пример, который я пытаюсь построить:

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';
}

Однако я бы хотел, чтобы это правильно, без использования этой кучки if elses, какие-либо предложения о том, как это сделать?

Спасибо.

Ответы [ 5 ]

4 голосов
/ 30 мая 2019

Вы можете использовать троичные выражения:

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)
1 голос
/ 30 мая 2019

Лучше рассматривать это как две разные условные строки, а затем соединять их вместе:

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;

Это позволяет вам рассуждать о полученной строке более прямым способом, чем рассматривать каждый возможный случай сразу,Только с двумя переменными у вас есть 4 возможных результата, а с 4 у вас будет 16 .

Разделение каждой переменной означает, что вам не нужно заботиться о других возможностях, когда вы генерируете каждую подстроку.

Вы можете еще больше упростить эту задачу, используя шаблоны.В этом случае вы можете отделить логику генерации строк в другом месте, чтобы сосредоточиться на разных вещах в разных областях

  • выяснить, каким должно быть каждое отдельное сообщение
  • выяснить, как их отобразить

Например, вы можете захотеть стандартизировать сообщения и получить что-то вроде:

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

, что позволит вам легче менять формат сообщений, не касаясь их.как они затем представляются.

Когда вы представляете их, вы можете захотеть, чтобы каждое сообщение было отдельной строкой, а не просто одной строкой, поэтому результат не должен зависеть от того, какие подмежа:

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;
}

Или вы можете полностью изменить эту реализацию:

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

  return finalString;
}

или изменить, чтобы отобразить их как маркеры HTML, возможно:

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

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

или что-нибудь еще.Дело в том, что проблемы теперь разделены.

0 голосов
/ 30 мая 2019

Действительно нечитаемое решение с использованием помеченных строк шаблона

function urlData(strings, ...values) {
  let [, def] = strings.slice().pop().split('|')
  return strings
     .slice(0, -1)
     .map((str, i) => `${str}${values[i]}`, '')
     .map((str, i) => values[i]?str:def)
     .reduce((msg, str, i) => `${msg}${str.replace (/:i/g, i+1)}`, '')
}

let url1 = 'http://example.com'
let url2 = undefined;

console.log(
  urlData `url 1 is ${url1} url 2 is ${url2} | there is no data for url :i`,
  urlData `url 1 is ${url2} url 2 is ${url1} | there is no data for url :i`,
  urlData `url 1 is ${url1} url 2 is ${url1} | there is no data for url :i`,
  urlData `url 1 is ${url2} url 2 is ${url2} | there is no data for url :i`
);
0 голосов
/ 30 мая 2019

Я уверен, что мы могли бы получить еще более точные данные с помощью троичных выражений:

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.'}
0 голосов
/ 30 мая 2019

1-й - использовать шаблоны строк ES6

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';
}

2-й - объединить и извлечь

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')}`
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...