![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Case of для строк
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;