![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Передача массива вариантов в функцию
Ega23 © (2015-03-25 12:39:00)Возникла нужда в рефакторинге. И вот что-то залип.
Нужен примерно такой код:
TSomeClass = class
private
FData: Variant;
FProcessors: TObjectList<TSomeProcessor>;
public
procedure MakeDataArray();
end;
TSomeProcessor = class
....
public
procedure FillData( ???? ); virtual;
end;
const
cDataArrWidth = 17;
procedure TSomeClass.MakeDataArray() ;
begin
FData := VarArrayCreate([0, SomeCount - 1, 1, cDataArrWidth], varVariant);
for i := 0 to FProcessors.Cpunt - 1 do
FProcessors.FillData( FData ???);
end;
Суть. Собираются данные для экспорта в Excel в виде двумерного массива. Поскольку данные неоднородны (где-то строки, а где-то в той же колонке могут быть и цифры), то создаётся эта байда как массив вариантов.
Дальше есть список неких "процессоров", которые этот массив по причудливой логике заполняют. Внутри процессоров размерность массива никак не изменяется.
Так вот, собственно, каким макаром мне этот мой FData: Variant; передавать в процессоры? Попробовал как вариант - у него vartype интересный, $800C. Т.е. и varArray и varVariant разом.
Пардон за сумбур. XE4.
(2015-10-20 20:38:00) [1]Удалено модератором
(2015-10-20 17:53:00) [2]Удалено модератором
junglecat (2015-03-26 11:49:00) [3]> или вы считаете, что varArray+varInteger - это не вариант?
почему же? по мне - так очень даже ничего вариант
han_malign (2015-03-26 11:47:00) [4]
> с одной стороны, это массив. С другой - вариант
- это массив вариантов...
или вы считаете, что varArray+varInteger - это не вариант?
han_malign (2015-03-26 11:43:00) [5]
> что варианты нельзя в VarType на равенство проверять, а надо по маске смотреть?
- дык там еще и varByRef- есть
а ссылка, массив и скаляр- это таки разные типы...
junglecat (2015-03-26 11:39:00) [6]ну, идеологически получается, что, с одной стороны, это массив. С другой - вариант, потому как и переменная объявлена как вариант и работать ты с ним можешь как с вариантом. Т.е. передать как параметр типа вариант в функцию
han_malign (2015-03-26 11:37:00) [7]varArray - это изначально флаг который комбинируется с типом элемента
unit Variants;
function VarArrayCreate(const Bounds: array of Integer;
AVarType: TVarType): Variant;
var
I, LDimCount: Integer;
LVarArrayRef: PVarArray;
LVarBounds: array[0..63] of TVarArrayBound;
begin
if (not Odd(High(Bounds)) or (High(Bounds) > 127)) or
(not VarTypeIsValidArrayType(AVarType)) then
VarArrayCreateError;
LDimCount := (High(Bounds) + 1) div 2;
for I := 0 to LDimCount - 1 do
with LVarBounds[I] do
begin
LowBound := Bounds[I * 2];
ElementCount := Bounds[I * 2 + 1] - LowBound + 1;
end;
LVarArrayRef := SafeArrayCreate(AVarType, LDimCount, PVarArrayBoundArray(@LVarBounds)^);
if LVarArrayRef = nil then
VarArrayCreateError;
_VarClear(TVarData(Result));
TVarData(Result).VType := AVarType or varArray;
TVarData(Result).VArray := LVarArrayRef;
end;
Ega23 (2015-03-26 11:23:00) [8]
> а кто сказал, что массив - не вариант? )
Дело не в этом. Дело в том, что в таком коде
var
v: Variant;
begin
v := VarArrayCreate(...);
end;
v после создания массива принимает тип (varArray or varVariant). А это меня в медитацию вогнало: получается, что варианты нельзя в VarType на равенство проверять, а надо по маске смотреть?
Jeer (2015-03-26 11:15:00) [9]>Испокон веков.
Да, точно - уже вылетело из головы, да использовал всегда [x,y]
[x][y] - это сишная конструкция, наверное потому и не пользовался.
junglecat (2015-03-26 11:08:00) [10]> тип варианта убил. varArray or varVariant
а кто сказал, что массив - не вариант? )
Ega23 (2015-03-26 11:06:00) [11]
> это еще повезло - на этапе компиляции обломалось
Меня больше всего тип варианта убил. varArray or varVariant
han_malign (2015-03-26 10:58:00) [12]
> Вот же... делфи!
- POD массив и SAFEARRAY- это две разные разницы
https://rsdn.ru/article/com/varsafearr.xml#E4NAC
это еще повезло - на этапе компиляции обломалось
т.к. _VarArrayGet
if LVarArrayPtr^.DimCount <> IndexCount then
VarResultCheck(VAR_BADINDEX);
Вот после VarArrayLock- получите классическую линейную развертку...
junglecat (2015-03-26 10:51:00) [13]> [14] Ega23 © (26.03.15 10:48)
наверно это от конкретной реализации в конкретной субд зависит.
возможно, где-то дистинкт реализован как вырожденный случай гроуп бай.
Но читабельней, конечно, дистинкт в данном случае )
Ega23 (2015-03-26 10:48:00) [14]
> накладные расходы в данном случае у distinct должны быть меньше.
На stackoverflow вроде вчера было сказано, что по-идее distinct быстрее, но в некоторых ситуациях (много полей например) сервер может и как group by отрабатывать. Но это уже оптимизатор сам решает, на его выбор повлиять можно далеко не всегда.
На самом деле я и не знал, что group by можно без агрегатов использовать. Для этих целей есть distinct. :)
Германн (2015-03-26 10:40:00) [15]
> Jeer © (26.03.15 10:21) [10]
>
> А когда это в Паскале или Делфи можно было использовать
> ar[x][y] ?
Испокон веков.
Пока не придумали варианты :)
junglecat (2015-03-26 10:38:00) [16]> по-поводу эквивалентности distinct и group by без аггрегатов
> в sql
накладные расходы в данном случае у distinct должны быть меньше. Он же тупо сортирует и убирает дубли
Ega23 (2015-03-26 10:34:00) [17]
> А когда это в Паскале или Делфи можно было использовать
> ar[x][y] ?
type
TFoo1 = array[1..2, 1..2] of Integer;
TFoo2 = array[1..2] of array[1..2] of Integer;
var
f1: TFoo1;
f2: TFoo2;
begin
f1[1, 1] := 1;
f1[1][2] := 2;
f2[1, 1] := 1;
f2[1][2] := 2;
end;
Только, ИМХО, тут самодисциплину надо включать.
Кстати, как раз вчерась диспут вышел, по-поводу эквивалентности distinct и group by без аггрегатов в sql. Сошлись на том, что хоть оно и эквивалентно в данной ситуации, правильнее писать distinct.
Jeer (2015-03-26 10:21:00) [18]А когда это в Паскале или Делфи можно было использовать ar[x][y] ?
Ega23 (2015-03-26 10:16:00) [19]
> Вот же... делфи!
Больше всего в этой фигне меня удивил тип варианта.
KilkennyCat (2015-03-26 09:55:00) [20]Вот же... делфи!