Как избежать операторов IF ELSE

У меня есть следующий код, который выглядит не очень красиво. Какие методы я мог бы использовать, чтобы сделать его лучше? Представьте, что есть много операторов IF ELSE. В качестве примера, я хотел бы различать, является ли левое меньше или больше, чем правое. Добавляются и другие расстояния. (Речь идет о роботе, который должен обнаруживать препятствия перед собой.)

distance1 = left_LOX.distance();
distance2 = middle_LOX.distance();
distance3 = right_LOX.distance();

if (distance1 < 100 || distance2 < 100 || distance3 < 100)
  distance_case = 1;
else if (distance1 < 300 || distance2 < 300 || distance3 < 300)
  distance_case = 2;
else
  distance_case = 3;

// Abfragen für die Automatik
switch (distance_case)
{
case 1:
  target = 0;
  robot.Stop();
  delay(2000);
  break;
case 2:
  target = 4000;
  robot.Forward();
  break;
case 3:
  target = 6000;
  robot.Forward();
  break;
}

Идея о том, как сделать это лучше, была бы хороша.

С или С++? Выбери один

463035818_is_not_a_number 17.01.2023 11:25

@ 463035818_is_not_a_number Для меня это не похоже на C.

Passer By 17.01.2023 11:26

то, что "хорошо" или "лучше" или то, что вы считаете "выглядеть лучше", является чисто субъективным. Я думаю, что код выглядит нормально

463035818_is_not_a_number 17.01.2023 11:27

Для 3 переменных это прекрасно. Для большего я бы рассмотрел массив и std::any_of

Yksisarvinen 17.01.2023 11:28

И для многих я бы рассмотрел возможность сортировки расстояний (или, возможно, объединения в диапазоны расстояний), чтобы было легче быстро определить, находятся ли они в определенных диапазонах.

Joris Timmermans 17.01.2023 11:30

Не устраняет большую часть «уродливого» кода, но удаляет if-else, если это то, что вы хотите: distance_case=(distance1<300 || distance2<300 || distance3<300) ? ((distance1<100 || distance2<100 || distance3<100) ? 1 : 2) : 3

Alexsen 17.01.2023 11:31

@Alexsen: if-else все еще существуют в виде ? и :, и этот код менее читаем. Так что ты выиграл?

Yves Daoust 17.01.2023 11:32

@YvesDaoust Синтаксис вложенности if-else был удален. Даже я упомянул, что уродство не было удалено. Он просто сжат, если-иначе.

Alexsen 17.01.2023 11:34

@Alexsen: нет, синтаксис вложения все еще существует через скобки.

Yves Daoust 17.01.2023 11:34

@Alexsen Это можно упростить (начиная с С++ 11) с помощью дополнительной переменной mindist = std::min({distance1, distance2, distance3}); distance_case = mindist < 300? ((mindist < 100) ? 1 : 2) : 3;

Peter 17.01.2023 11:35

@YvesDaoust может быть личным предпочтением, но я предпочитаю синтаксис ? x : y пирамидам if-else.

Alexsen 17.01.2023 11:35

@Peter Питер На самом деле это гораздо лучше, я бы даже подумал над ответом, если хочешь записать это.

Alexsen 17.01.2023 11:36

Я прошу прощения за неправильное понимание моих тегов. Это esp32. И esp32 поддерживает C и C++, верно?

Teebow 17.01.2023 11:43

Здесь именно переключатель кажется излишним. std::min({distance1, distance2, distance3}) может храниться в переменной для упрощения условий.

Jarod42 17.01.2023 16:53
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
14
129
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вы можете добавить, если это выглядит лучше для вас.

distance_case = (distance1 < 100 || distance2 < 100 || distance3 < 100) + 
                (distance1 < 300 || distance2 < 300 || distance3 < 300) + 
                (distance1 >= 300 || distance2 >= 300 || distance3 >= 300);

Вы даже можете пропустить первую часть и использовать 1+(>=100)+(>=300)

Alexsen 17.01.2023 11:38

вы можете использовать блок if ... else if ... else напрямую, если distance_case не используется в течение длительного времени. Он излишне вводит новые переменные, которые не имеют смысла. Или определите enum, если вы видите, что в долгосрочной перспективе таких случаев будет много. Читатель также может быстро разобраться в значениях.

Это скорее комментарий, а не ответ

0___________ 17.01.2023 11:35

Итак, вы решили злоупотребить системой, потому что вам не хватает репутации. Просто пишите больше реальных ответов и получайте репутацию. Это ограничение не просто так. никогда не используйте ответы в качестве комментариев здесь. я

0___________ 17.01.2023 11:38
dmin= min(left_LOX.distance(), middle_LOX.distance(), right_LOX.distance());
if (dmin < 100)
{
    target = 0;
    robot.Stop();
    delay(2000);
}
else if (dmin < 300)
{
   target = 4000;
   robot.Forward();
}
else
{
   target = 6000;
   robot.Forward();
}
Ответ принят как подходящий

Если у вас много расстояний (сотни, тысячи), то проще сначала сгруппировать все расстояния в контейнер типа вектор, а потом использовать стандартные алгоритмы. Например. что-то вроде этого: Это предполагает, что у вас есть стандартная библиотека С++, доступная на используемой вами платформе/компиляторе esp32 — это должно быть возможно, по крайней мере, до С++ 11 — см., например. https://medium.com/geekculture/modern-c-with-esp32-dcd3918dd978.

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
    // Just an example vector initialisation - replace this with the required x_Lox.distance() calls.
    std::vector<int> distances = {300, 500, 500, 200, 100 };
    const auto min = *std::min_element(distances.begin(), distances.end());
    
    std::cout << "Min distance: " << min;

    return 0;
}

Как только у вас будет минимальное расстояние, вы можете просмотреть различные случаи для обработки. Это основано на предположении, что вас интересует только кратчайшее расстояние для выбора действия вашего робота. Если у вас более сложная логика, код также становится более сложным.

Вы разыменовываете std::min, это опечатка?

Fabio says Reinstate Monica 17.01.2023 11:46

@FabiosaysReinstateMonica да, спасибо! - Очевидно, я хотел использовать std::min_element, потому что сравнение итераторов по размеру довольно бесполезно ;-)

Joris Timmermans 17.01.2023 11:55

Это выглядит хорошо. Вы знаете, может ли esp32 обрабатывать векторы?

Teebow 17.01.2023 11:59

Если у вас более сложная логика, код также становится более сложным. К сожалению, я должен это сделать.

Teebow 17.01.2023 12:01

@Teebow Чтобы помочь с логикой, которая более сложна, чем основанная на текущем минимальном расстоянии, нам нужно увидеть примеры этой логики. Нет «общего» ответа, например. некоторые из них могут быть основаны на размещении расстояний в ведрах - сколько расстояний меньше 300, сколько дальше 600 и т. д. Похоже, среда программирования esp32 должна обеспечивать доступ к современному C++.

Joris Timmermans 17.01.2023 13:14

@JorisTimmermans хорошо, я вижу. К сожалению, я пока не могу привести пример более сложных инструкций. Но ваш ответ мне уже очень помог, я думаю. Я посмотрю на это поближе.

Teebow 17.01.2023 16:37

@Teebow - в библиотеке std::algorithm может быть много интересного, что вы можете сделать с контейнером расстояний. Или даже контейнер объектов, который включает в себя расстояния и другие вещи, необходимые для вашей логики. Есть минимум и максимум, поиск предикатов, фильтрация, преобразование...

Joris Timmermans 18.01.2023 09:22

@Teebow, если вы считаете, что этот или любой другой ответ достаточно решил вашу проблему, не могли бы вы принять его?

Joris Timmermans 20.01.2023 10:19

@JorisTimmermans Извините, я забыл об этом.

Teebow 22.01.2023 13:31

Другие вопросы по теме