Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Case of для строк


Страницы:   1 2 3

ford ©   (2010-03-31 17:24:00) 

Здравствуйте!
в программу передается параметр от которого зависит какая из процедур должна быть выполнена. Значений параметра около десятка.

я сделал следующим образом

if ParamStr(1)='create' then createnewfile(paramstr(2))
 else if ParamStr(1)='send' then sendfile(paramstr(2))
       else ....


подскажите, можно ли реализовать это как Case of
т.е. примерно так:


Case ParamStr(1) of
'create' : createnewfile(paramstr(2));
'send'   : sendfile(paramstr(2));
...
else
...
end;


понятно что Case не работает для строк
но все же :)


Демо   (2010-03-31 17:39:00) [41]

Вот. Просто копирую сюда.

Case для строк

Часто бывает, что нужно проверить строку на совпадение с рядом заранее заданных значений. Case для этого подходит идеально, но, к сожалению, он работает только с перечислимыми типами. Приходится использовать ряд сравнений, и если набор сравниваемых значений превышает 5 элементов, код превращается в маловразумительную городушку из if-then-else.

Можно, конечно, загнать варианты в TStringList - но придётся заботиться о создании/удалении. Статическая константа-массив тоже не всегда выход. Задачу можно решить с помощью безымянной константы-массива.

...
 case IndexStr(s, ['variant 1', 'variant 2', 'variant 3', 'variant 4', 'variant 5', 'variant 6', 'variant 7'] ) of
   0:   idx := 0; // or do something
   1:   idx := 1; // or do something
   2:   idx := 2; // --- || ---
   3:   idx := 3;
   4:   idx := 4;
   5:   idx := 5;
   6:   idx := 6;
   7:   idx := 7;
   else idx := -1; // not found
 end;
...



Также можно составлять массив и из переменных:
 case IndexStr(s, [Form1.Caption, Button1.Caption, Edit1.Text] ) of

Проведя ряд тестов, я выяснил, что IndexStr (она же AnsiIndexStr) очень неэффективна: она вызывает WinAPI функцию CompareString, да еще и с двумя вложенными вызовами. Но если использовать свою функцию, которая будет просто сравнивать строки

function NewIndexStr(const AText: string; const AValues: array of string): Integer;
var
 I: Integer;
begin
 Result := -1;
 for I := Low(AValues) to High(AValues) do
   if AText = AValues[I] then
   begin
     Result := I;
     Break;
   end;
end;


то скорость по сравнению с многоступенчатыми if-then-else будет идентична и даже немного выше.

Более того, этот метод можно легко приспособить для любых типов: указатели, вещественные числа, записи - достаточно лишь модифицировать объявление у функции поиска. Также, подозреваю, можно использовать Variant типы и функцию VarSameValue, но мне пока не удалось понять, как перейти от TVarData к Variant.


Демо   (2010-03-31 17:38:00) [42]


> Игорь Шевченко ©   (31.03.10 17:37) [3]
> Демо ©   (31.03.10 17:33) [2] Че, такой секретный форум
> ? "У вас нет прав для просмотра этой темы"


Странно. Там заготовки для FAQ лежат.


Игорь Шевченко   (2010-03-31 17:37:00) [43]

Демо ©   (31.03.10 17:33) [2]

Че, такой секретный форум ? "У вас нет прав для просмотра этой темы"


Демо   (2010-03-31 17:33:00) [44]

Посмотри здесь.
Мало-ли, может понравится приём.

http://forum.sources.ru/index.php?showtopic=299079


12   (2010-03-31 17:30:00) [45]

Завести массив соответствий типа
'create' - 1
'send'- 2

функцию преобразования

case Func(ParamStr(1)) of
1:
2:
else
end;


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо