Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Подскажите вариант CASE ... OF с условиями / 25 сообщений из 58, страница 1 из 3
04.04.2019, 11:06
    #39796262
Artem.1st
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант CASE ... OF с условиями
На практике встречается длинная цепочка операторов: If () Then

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
if ( {условие-1} ) then begin {действия-1} end 
else
  if ( {условие-2} ) then begin {действия-2} end
  else
    if ({условие-3} ) then begin {действия-3} end
    else
      if ( {условие-4} ) then begin {действия-4} end 
      else
         // ...  и т.д. ОЧЕНЬ длинная конструкция 


Когда более 10 условий, то код становится трудно-читаемым.
К сожалению case () of здесь нельзя использовать, т.к. условия - вычисляемые.

Уважаемые гуру, как вы оформляете такой Delphi код?

Спасибо.
...
Рейтинг: 0 / 0
04.04.2019, 11:09
    #39796267
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант CASE ... OF с условиями
Оформляй без сдвига
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
if ( {условие-1} ) then begin
  {действия-1} 
end else
if ( {условие-2} ) then begin 
  {действия-2}
end else
if ( {условие-3} ) then begin 
  {действия-3} 
end else
if ( {условие-4} ) then begin
 {действия-4}
end else
...
Рейтинг: 0 / 0
04.04.2019, 11:09
    #39796268
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант CASE ... OF с условиями
Artem.1stт.к. условия - вычисляемые.
Например?
...
Рейтинг: 0 / 0
04.04.2019, 11:09
    #39796269
sasha27
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант CASE ... OF с условиями
Artem.1st,

Покажите результаты условия
...
Рейтинг: 0 / 0
04.04.2019, 11:13
    #39796273
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант CASE ... OF с условиями
Artem.1st,

Я не гуру, но как-то так:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
if ( {условие-1} ) then begin 
  {действия-1} 

end else if ( {условие-2} ) then begin 
  {действия-2} 

end else if ( {условие-3} ) then begin 
  {действия-3} 

end else if ( {условие-4} ) then begin 
  {действия-4} 

end else if // ...  и т.д. ОЧЕНЬ длинная конструкция 
...
Рейтинг: 0 / 0
04.04.2019, 11:17
    #39796279
Artem.1st
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант CASE ... OF с условиями
wadmanArtem.1stт.к. условия - вычисляемые.
Например?
Код: pascal
1.
2.
3.
4.
5.
6.
7.
if ( ParamStr(0) = '/Help' ) then begin {действия-1} end 
else
  if ( ParamStr(0) = '/Start' ) then begin {действия-2} end
  else
    if (ParamStr(0) = '/Wait' ) then begin {действия-3} end
    else
      ....


Это абстрактный пример, а у меня все сложнее.
В help написано, что сase () of требует констатнты и только перечислимого типа, т.е. даже String нельзя использовать.

И как бороться с такими конструкциями?
...
Рейтинг: 0 / 0
04.04.2019, 11:20
    #39796283
zinpub
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант CASE ... OF с условиями
Artem.1st,

Ну если очень хочеться именно case .. of

то можно написать функцию приведения в которой будут те же if'ы
...
Рейтинг: 0 / 0
04.04.2019, 11:26
    #39796291
zinpub
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант CASE ... OF с условиями
Как-то так ...

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
type
  TMyParam = (mpHelp, mpStart, mpWait);
  
const 
  aMyParamTxt = array[mpHelp..mpWait] of string = ('/Help', '/Start', '/Wait'); 

...

function StrToMyParam(const iStr: string): TMyParam;
var
  aParam: TMyParam;
begin
  for aParam:= mpHelp to mpWait do
      if aMyParamTxt[aParam] = iStr then
	  begin
	    Result:= aParam;
		Exit;
	  end;
end;
...
Рейтинг: 0 / 0
04.04.2019, 11:27
    #39796292
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант CASE ... OF с условиями
Код: pascal
1.
2.
3.
4.
5.
case IndexStr(ParamStr(0), ['/Help', '/Start', '/Wait']) of 
  0: ; // Help
  1: ; // Start
  2: ; // Wait
end;
...
Рейтинг: 0 / 0
04.04.2019, 12:05
    #39796334
High.Programer
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант CASE ... OF с условиями
zinpubКак-то так ...
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
type
  TMyParam = (mpHelp, mpStart, mpWait);
  
const 
  aMyParamTxt = array[mpHelp..mpWait] of string = ('/Help', '/Start', '/Wait'); 

...

function StrToMyParam(const iStr: string): TMyParam;
var
  aParam: TMyParam;
begin
  for aParam:= mpHelp to mpWait do
      if aMyParamTxt[aParam] = iStr then
	  begin
	    Result:= aParam;
		Exit;
	  end;
end;


Hint: "Result - может не вернуть значение."
ОК. Закроем на это глаза, но зачем 8(восемь) строк, когда достаточно всего 2(две) строки:
Код: pascal
1.
2.
3.
4.
5.
function StrToMyParam(const iStr: string): TMyParam;
begin
  for Result in mpHelp do
    if aMyParamTxt[Result] = iStr then Exit;
end;
...
Рейтинг: 0 / 0
04.04.2019, 12:07
    #39796338
zinpub
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант CASE ... OF с условиями
High.Programer,

1. Ну это ж прототип...

2. Result после for не имеет гарантированного значения...
...
Рейтинг: 0 / 0
04.04.2019, 12:08
    #39796341
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант CASE ... OF с условиями
High.ProgramerОК. Закроем на это глаза, но зачем 8(восемь) строк, когда достаточно всего 2(две) строки:
Код: pascal
1.
2.
3.
4.
5.
function StrToMyParam(const iStr: string): TMyParam;
begin
  for Result in mpHelp do
    if aMyParamTxt[Result] = iStr then Exit;
end;


Надо ещё в конце (и в тип) добавить что-то вроде
Код: pascal
1.
Result := mpUnknown;

иначе может нежданчик случиться.
...
Рейтинг: 0 / 0
04.04.2019, 12:09
    #39796342
High.Programer
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант CASE ... OF с условиями
выше была очепятка.
Оператор FOR...IN доступен с Delphi 2005:
Код: pascal
1.
2.
3.
4.
5.
function StrToMyParam(const iStr: string): TMyParam;
begin
  for Result in aMyParamTxt do
    if aMyParamTxt[Result] = iStr then Exit;
end;
...
Рейтинг: 0 / 0
04.04.2019, 12:15
    #39796349
High.Programer
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант CASE ... OF с условиями
zinpub2. Result после for не имеет гарантированного значения...
Я не проверял, но помню, что это переменная цикла после индексного перебора For i:=0 to Count-1 do имеет неопределенное значения. А в нашем случае не индексный перебор, а последовательный(через энумератор)
...
Рейтинг: 0 / 0
04.04.2019, 12:22
    #39796352
makhaon
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант CASE ... OF с условиями
Зачем велосипеды? IndexStr есть же.
...
Рейтинг: 0 / 0
04.04.2019, 12:28
    #39796360
zinpub
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант CASE ... OF с условиями
High.Programer,

А какая разница? Что происходит с итератором - мало предсказуемо...
...
Рейтинг: 0 / 0
04.04.2019, 12:29
    #39796362
zinpub
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант CASE ... OF с условиями
makhaonЗачем велосипеды? IndexStr есть же.

Для данного случая да, но если логика усложнится...
...
Рейтинг: 0 / 0
04.04.2019, 12:31
    #39796367
Artem.1st
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант CASE ... OF с условиями
High.Programer ,
For..In использвоать боюсь, т.к. в детстве не приучили
:-)

zinpub, DimaBr ,
спасибо за идею. Проблема String для Case..OF решается, хотя для более сложных условий придется выстраивать многочисленные if then.
Похоже, не только в Delphi, я посмотрел в других языках C++, Java также "Switch" не помогает
:-(
...
Рейтинг: 0 / 0
04.04.2019, 12:57
    #39796403
mbb
mbb
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант CASE ... OF с условиями
Как-то раз вот так сделал:

case Ord(<Усл1>) * 1 +
Ord(<Усл2>) * 2 +
Ord(<Усл3>) * 3
of
1:...
2:...
3;...
end;
...
Рейтинг: 0 / 0
04.04.2019, 13:37
    #39796448
Valery_B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант CASE ... OF с условиями
Artem.1stкак вы оформляете такой Delphi код?

Через список TList<TWorkerClass> или TObjectDictionary<string,TWorkerClass>
Код: pascal
1.
2.
3.
4.
5.
6.
7.
var
 Dict:ObjectDictionary<string,TWorkerClass>;
 s:string;
begin
 for s in Dict.Keys do 
  Dict[s].Work;
end;
...
Рейтинг: 0 / 0
04.04.2019, 14:22
    #39796488
Michael Longneck
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант CASE ... OF с условиями
И зачем двойной доступ в Dictionary?


Код: pascal
1.
2.
3.
4.
5.
6.
7.
var
  Dict:ObjectDictionary<string,TWorkerClass>;
  Item: TPair<string,TWorkerClass>;
begin
  for Item in Dict do 
    Item.Value.Work;
end;
...
Рейтинг: 0 / 0
04.04.2019, 14:44
    #39796510
Valery_B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант CASE ... OF с условиями
Michael Longneck,

Тогда уж так.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
var
 Dict:ObjectDictionary<string,TWorkerClass>;
 Worker: TWorkerClass;
begin
 for Worker in Dict.Values do 
  Worker.Work;
end;
...
Рейтинг: 0 / 0
04.04.2019, 15:58
    #39796616
Foxpc
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант CASE ... OF с условиями
Чё уж? Давайте пировать!

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
    InteractiveCallBack(ParamStr(0), 3,
    '/Help', procedure
      begin
        Writeln('Help');
      end,
    '/start', procedure
      begin
        Writeln('start');
      end,
    '/Wait', procedure
      begin
        Writeln('Wait');
      end);



Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
unit InteractiveCallBackUnit;

interface

type
  TEventInteractiveNotify = Reference to procedure();

  InteractiveCallBackTmp2 = procedure(const Str1: string; Count: Integer; Name: string;
    E: TEventInteractiveNotify)Cdecl Varargs;

  TvaArgs = record
  const
    SizeAlign = SizeOf(NativeUint) - 1;
  private
    FPtr: PByte;
  public
    constructor Create(LastArg: Pointer; Size: Integer);
    function Read<T>(): T;
  end;

var
  InteractiveCallBack: InteractiveCallBackTmp2;

implementation

constructor TvaArgs.Create(LastArg: Pointer; Size: Integer);
begin
  FPtr := PByte(NativeUint(PByte(LastArg) + Size + SizeAlign) and not SizeAlign);
end;

function TvaArgs.Read<T>(): T;
begin
  Move(FPtr^, Result, SizeOf(T));
  FPtr := PByte(NativeUint(PByte(FPtr) + SizeOf(T) + SizeAlign) and not SizeAlign);
end;

procedure InteractiveCallBackTmp(const Str1: string; Count: Integer; Name: string;
  E: TEventInteractiveNotify); cdecl; // varargs;
var
  Va: TvaArgs;
  Str2: string;
  Event: Pointer;
begin
  Va := TvaArgs.Create(@Count, SizeOf(Integer));
  while Count >= 1 do
  begin
    Str2 := Va.Read<string>;
    Event := Va.Read<Pointer>;
    if Str1 = Str2 then
    begin
      TEventInteractiveNotify(Event)();
      Exit;
    end;
    Dec(Count);
  end;
end;

initialization

InteractiveCallBack := InteractiveCallBackTmp;

finalization

end.

...
Рейтинг: 0 / 0
04.04.2019, 16:00
    #39796620
Foxpc
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант CASE ... OF с условиями
Под 64 битную платформу подправил
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
unit InteractiveCallBackUnit;

interface

type
  TEventInteractiveNotify = Reference to procedure();

  InteractiveCallBackTmp2 = procedure(const Str1: string; Count: Integer; Name: string;
    E: TEventInteractiveNotify)Cdecl Varargs;

  TvaArgs = record
  const
    SizeAlign = SizeOf(NativeUint) - 1;
  private
    FPtr: PByte;
  public
    constructor Create(LastArg: Pointer; Size: NativeUint);
    function Read<T>(): T;
  end;

var
  InteractiveCallBack: InteractiveCallBackTmp2;

implementation

constructor TvaArgs.Create(LastArg: Pointer; Size: NativeUint);
begin
  FPtr := PByte(NativeUint(PByte(LastArg) + Size + SizeAlign) and not SizeAlign);
end;

function TvaArgs.Read<T>(): T;
begin
  Move(FPtr^, Result, SizeOf(T));
  FPtr := PByte(NativeUint(PByte(FPtr) + SizeOf(T) + SizeAlign) and not SizeAlign);
end;

procedure InteractiveCallBackTmp(const Str1: string; Count: Integer; Name: string;
  E: TEventInteractiveNotify); cdecl; // varargs;
var
  Va: TvaArgs;
  Str2: string;
  Event: Pointer;
begin
  Va := TvaArgs.Create(@Count, SizeOf(NativeUint));
  while Count >= 1 do
  begin
    Str2 := Va.Read<string>;
    Event := Va.Read<Pointer>;
    if Str1 = Str2 then
    begin
      TEventInteractiveNotify(Event)();
      Exit;
    end;
    Dec(Count);
  end;
end;

initialization

InteractiveCallBack := InteractiveCallBackTmp;

finalization

end.

...
Рейтинг: 0 / 0
04.04.2019, 17:32
    #39796717
Василий 2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите вариант CASE ... OF с условиями
Artem.1stНа практике встречается длинная цепочка операторов: If () Then

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
if ( {условие-1} ) then begin {действия-1} end 
else
  if ( {условие-2} ) then begin {действия-2} end
  else
    if ({условие-3} ) then begin {действия-3} end
    else
      if ( {условие-4} ) then begin {действия-4} end 
      else
         // ...  и т.д. ОЧЕНЬ длинная конструкция 


Уважаемые гуру, как вы оформляете такой Delphi код?

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
if ( {условие-1} ) then
begin
  {действия-1} 
end
else if ( {условие-2} ) then
begin 
  {действия-2}
end
else if ( {условие-3} ) then
begin 
  {действия-3} 
end
else if ( {условие-4} ) then
begin
 {действия-4}
end
else
...



Либо, если позволяет код, вынести в подпрограмму, тогда:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
if ( {условие-1} ) then
begin
  {действия-1} 
  Exit;
end
if ( {условие-2} ) then
begin 
  {действия-2}
  Exit;
end
if ( {условие-3} ) then
begin 
  {действия-3} 
  Exit;
end
if ( {условие-4} ) then
begin
 {действия-4}
  Exit;
end
...



Либо, если не получается, обернуть в try-finally
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
try
if ( {условие-1} ) then
begin
  {действия-1} 
  Exit;
end
if ( {условие-2} ) then
begin 
  {действия-2}
  Exit;
end
if ( {условие-3} ) then
begin 
  {действия-3} 
  Exit;
end
if ( {условие-4} ) then
begin
 {действия-4}
  Exit;
end
...
finally
...выполнится для всех случаев
end;
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Подскажите вариант CASE ... OF с условиями / 25 сообщений из 58, страница 1 из 3
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]