У меня много условий, и если бы я написал его с if ... иначе он работает нормально, но может быть трудно читать другим (особенно, если он будет расти в будущем). Есть ли способ лучше, как его переписать на более ...

-2
user15308065 2 Мар 2021 в 14:40

8 ответов

Лучший ответ

На ум приходят два способа, но ни один из них не сделает ваш код очень ясным, потому что условия - грязная штука.

  1. Если вы вернете логическое значение, вам не нужны блоки if..else. Просто верните условия.
func(el) => {
  return (el.type === 'Cars' && el.label) ||
         (el.type === 'Bikes' && 
             (el.storage?.filter(el => el.id == 1).length >= 1 ||
              el.storage?.filter(el => el.id == 2).length > 1)
         )
}
  1. Вы можете выделить группу условий для разделения функций и вызвать их в основной функции.
const checkForCars = (el) => { return el.type === 'Cars' && el.label }
const checkForBikes = (el) => { return // your conditions}
const mainFunction (el) {
   return checkForCars(el) || checkForBikes(el);
}
1
Bülent Akgül 2 Мар 2021 в 11:59

привет, я немного оптимизирую. Я бы хотел, чтобы это могло вам помочь.

const oldFunc = (el) => {
    if (el.type === 'News' && el.label) {
        return true;
    }
    if (el.type === 'Research' && el.storage) {
        if (el.storage.filter(el => el.id === 1).length >= 1) {
            return true;
        }
        if (el.storage.filter(el => el.id === 2).length > 1) {
            return true;
        }
    } else return false;
}

// do some optimize
const newFunc = (el) => {
    let flag = false;// default return false
    flag = ((el.type === 'News' && el.label) || 
    ((el.type === 'Research' && el.hasOwnProperty('storage')) ? el.storage.some(o=>[1,2].includes(o.id)): false)) && true;
    return flag;
}

// test code
const testData = {
    type: 'News',
    label: 'test'
};

console.log(oldFunc(testData));
console.log(newFunc(testData));

const testData2 = {
    type: 'Research',
    storage: [
        {
            id: 1,
            name: "John"
        }
    ]
};

console.log(oldFunc(testData2));
console.log(newFunc(testData2));

// test result
// true
// true
// true
// true
1
morgan-wu 2 Мар 2021 в 11:57

Если вы спросите меня, я создаю функцию, которая считает значение, и код будет более читабельным.

function count(arr, tar) {
  cnt = 0;
  for(let val of arr) {
    if(val === tar)
      cnt += 1;
  }
  return cnt;
}

Вы можете написать свою функцию таким образом, это для меня более читабельно:

const func = (el) => {
    if (el.type === 'Cars' && el.label)
    return true;
    
  if (el.type === 'Bikes' && el.storage)
    if(count(el.storage,1) >= 1 || count(el.storage,2) > 1)
        return true;
      
  return false;
}

Или так:

const func = (el) => {
  if (el.type === 'Cars' && el.label)
    return true;
        
  if ((el.type === 'Bikes' && el.storage) &&
     (count(el.storage,1) >= 1 || count(el.storage,2) > 1))
    return true;

return false;

Так как это гораздо более читабельно, однако вы можете изменить функцию count на любой другой способ, который вам нравится, и я бы предпочел использовать этот код, даже если он длиннее, но он намного читабельнее.

1
Raz K 2 Мар 2021 в 12:19

Вы пробовали использовать корпус выключателя? Например:

function(el)=>{
switch(el.type):
  case 'Cars':
    return true;
    break;
  case 'Bikes':
    return true;
    break;
  default:
    return false;
}

После этого вы, возможно, можете поставить if-else перед словом return в каждом случае.

0
Ajinkya 2 Мар 2021 в 11:50

Я обычно стараюсь быть как можно более информативным. Переименуйте func в то, что делает функция.

Для удобства чтения вы также можете создать функцию в el с именем, isCar(), isBike(), hasStorage() и т. Д., Которая инкапсулирует эту логику. Я не уверен, что это имеет смысл, исходя из того, что вы предоставили. Вы также используете встроенные идентификаторы жесткого кодирования. Было бы понятнее, если бы el содержал некоторые const / var или что-то в вашем приложении было их, что описывало идентификатор. Вы также можете переименовать el во что-нибудь описательное. Вы можете удалить часть if, выполнив то, что сказал Гуэррик П.

Даже функции фильтра можно было бы переместить, если бы они собирались использовать повторно.

const shedFilter = (el) => ...(function code here)

Затем сделайте несколько комментариев, если что-то не ясно.

const STORAGE_SHED = 1;
const SOTRAGE_GARAGE = 2;

aGoodName(el) => {
  if (el.isCar()) { return true; }
  if (el.isBike()) {
    if (el.storage.filter(el => el.id === STORAGE_SHED ).length >= 1) { return true; }
    if (el.storage.filter(el => el.id === SOTRAGE_GARAGE).length > 1) { return true; }
  } 
else { return false };
}
0
Allan 2 Мар 2021 в 12:06

Шаг 1: Чтобы иметь ту же логику, что и у вас, вы можете начать с извлечения условий / функции и попытаться избежать операторов return true и return false. Вы можете легко вернуть само состояние.

  const isNews = el.type === 'News' && el.label;
  const isBikes = el.type === 'Bikes' && el.storage;
  const storageItemsCount = (el, id) => el.storage.filter(el.id === id).length;

  return isNews 
           || (isBikes && (storageItemsCount(el, 1) >= 1 || storageItemsCount(el, 2) > 1)

Шаг 2: далее я бы удалил значения "magic" id 1 и 2 и явно указал, о чем они говорят, например

const BIKE1_ID = 1;
const BIKE2_ID = 2;

Нет, мы можем обобщить проверку подсчетов, указав

const minBikeCounts = {
  [BIKE1_ID]: 1,
  [BIKE1_ID]: 2
}

const bikeCountsAreValid = el => {
   return Object.entries(k)
          .every(
             ([id, minCount]) => el.storage.filter(el => el.id === key).length >= minCount)
}

Поэтому основной поток упростился до

const isNews = el.type === 'News' && el.label;
const isBikes = el.type === 'Bikes' && el.storage;

return isNews || (isBikes && bikeCountsAreValid(el))

Шаг 3. Мы видим шаблон «Проверить, поддерживается ли тип, с дополнительной проверкой» . Мы можем извлечь информацию о поддерживаемых типах для разделения структуры. Теперь, если мы хотим добавить новый поддерживаемый тип, нам не нужно запоминать все операторы if/else в кодовой базе, а просто добавить здесь новый:

const supportedTypes = {
 News: el => !!el.label,
 Bikes: el => !!el.storage && bikeCountsAreValid(el)
}

Никаких операторов if в нашей основной функции:

const isSuppotedType = 
   (el: IHeadlines) => supportedTypes[el.type] && supportedTypes[el.type](el)
0
udalmik 2 Мар 2021 в 12:23

Хорошие практики чистого кода предполагают, что у вас есть небольшие функции и код с самоописанием.

В вашем коде я бы сделал каждую логическую логику переменной или функцией.

Пример 1

func(element: IHeadlines): boolean => {
    const isCarWithLabel = element.type === 'Cars' && element.label;

    if(isCarWithLabel){
        return true;
    }
    const isBikeWithStorage = element.type === 'Bikes' && element.storage;

    if(isBikeWithStorage){
        // rest of your logic that I don't know...
    }
    return false;
}

Пример 2

func(element: IHeadlines): boolean => {
    return this.isCarWithLabel() || this.isBikeWithStorageAndSomethingElse();
}
0
Samir Sales 2 Мар 2021 в 12:34

Ваш код можно упростить с помощью одного такого выражения:

const func = (el) => {
  return !!(
    (el.type === "News" && el.label) ||
    (el.type === "Research" &&
      el.storage &&
      (el.storage.filter((el) => el.id === 1).length >= 1 ||
        el.storage.filter((el) => el.id === 2).length > 1))
  );
};
-2
Guerric P 2 Мар 2021 в 12:28