Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2017.08.27;
Скачать: [xml.tar.bz2];

Вниз

Передача массива вариантов в функцию   Найти похожие ветки 

 
Ega23 ©   (2015-03-25 12:39) [0]

Возникла нужда в рефакторинге. И вот что-то залип.
Нужен примерно такой код:

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.


 
Ega23 ©   (2015-03-25 13:08) [1]

Вопрос снят. Тупанул, обращался к двумерному массиву через [i][j], вместо [i, j]

А передавать надо так:


TSomeProcessor = class
....
public
procedure FillData(var Data: Variant); virtual;
end;


 
Германн ©   (2015-03-25 13:40) [2]


> Тупанул, обращался к двумерному массиву через [i][j], вместо
> [i, j]

А разве это не одно и то же?


 
Ega23 ©   (2015-03-25 16:09) [3]


> А разве это не одно и то же?


не совсем.


 
Германн ©   (2015-03-26 01:42) [4]


> Ega23 ©   (25.03.15 16:09) [3]
>
>
> > А разве это не одно и то же?
>
>
> не совсем.
>

Почему не совсем? В каком случае [i][j] не годится?


 
Ega23 ©   (2015-03-26 02:34) [5]


> В каком случае [i][j] не годится?


В том тесте, который я наваял.
Завтра (точнее - утром... гм... после 10, короче) код выложу.


 
KilkennyCat ©   (2015-03-26 03:19) [6]

любопытно.
по крайней мере, здесь http://docwiki.embarcadero.com/RADStudio/XE6/en/Structured_Types утверждается, что оба обращения эквивалентны


 
Ega23 ©   (2015-03-26 09:16) [7]


> что оба обращения эквивалентны



procedure TForm32.Bar3(var V: Variant);
begin
 V[1, 1] := 1;
end;

Работает.


procedure TForm32.Bar3(var V: Variant);
begin
 V[1][1] := 1;
end;

E2064 Left side cannot be assigned to


 
KilkennyCat ©   (2015-03-26 09:55) [8]

Вот же... делфи!


 
Ega23 ©   (2015-03-26 10:16) [9]


> Вот же... делфи!


Больше всего в этой фигне меня удивил тип варианта.


 
Jeer ©   (2015-03-26 10:21) [10]

А когда это в Паскале или Делфи можно было использовать ar[x][y] ?


 
Ega23 ©   (2015-03-26 10:34) [11]


> А когда это в Паскале или Делфи можно было использовать
> 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.


 
junglecat ©   (2015-03-26 10:38) [12]

> по-поводу эквивалентности distinct и group by без аггрегатов
> в sql

накладные расходы в данном случае у distinct должны быть меньше. Он же тупо сортирует и убирает дубли


 
Германн ©   (2015-03-26 10:40) [13]


> Jeer ©   (26.03.15 10:21) [10]
>
> А когда это в Паскале или Делфи можно было использовать
> ar[x][y] ?

Испокон веков.
Пока не придумали варианты :)


 
Ega23 ©   (2015-03-26 10:48) [14]


> накладные расходы в данном случае у distinct должны быть меньше.


На stackoverflow вроде вчера было сказано, что по-идее distinct быстрее, но в некоторых ситуациях (много полей например) сервер может и как group by отрабатывать. Но это уже оптимизатор сам решает, на его выбор повлиять можно далеко не всегда.

На самом деле я и не знал, что group by можно без агрегатов использовать. Для этих целей есть distinct. :)


 
junglecat ©   (2015-03-26 10:51) [15]

> [14] Ega23 ©   (26.03.15 10:48)

наверно это от конкретной реализации в конкретной субд зависит.
возможно, где-то дистинкт реализован как вырожденный случай гроуп бай.
Но читабельней, конечно, дистинкт в данном случае )


 
han_malign ©   (2015-03-26 10:58) [16]


> Вот же... делфи!

- POD массив и SAFEARRAY - это две разные разницы
https://rsdn.ru/article/com/varsafearr.xml#E4NAC

это еще повезло - на этапе компиляции обломалось
т.к. _VarArrayGet
 if LVarArrayPtr^.DimCount <> IndexCount then
   VarResultCheck(VAR_BADINDEX);


Вот после VarArrayLock - получите классическую линейную развертку...


 
Ega23 ©   (2015-03-26 11:06) [17]


> это еще повезло - на этапе компиляции обломалось

Меня больше всего тип варианта убил. varArray or varVariant


 
junglecat ©   (2015-03-26 11:08) [18]

> тип варианта убил. varArray or varVariant

а кто сказал, что массив - не вариант? )


 
Jeer ©   (2015-03-26 11:15) [19]

>Испокон веков.
Да, точно - уже вылетело из головы, да использовал всегда [x,y]
[x][y] - это сишная конструкция, наверное потому и не пользовался.


 
Ega23 ©   (2015-03-26 11:23) [20]


> а кто сказал, что массив - не вариант? )


Дело не в этом. Дело в том, что в таком коде

var
 v: Variant;
begin
 v := VarArrayCreate(...);
end;

v после создания массива принимает тип (varArray or varVariant). А это меня в медитацию вогнало: получается, что варианты нельзя в VarType на равенство проверять, а надо по маске смотреть?


 
han_malign ©   (2015-03-26 11:37) [21]

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;


 
junglecat ©   (2015-03-26 11:39) [22]

ну, идеологически получается, что, с одной стороны, это массив. С другой - вариант, потому как и переменная объявлена как вариант и работать ты с ним можешь как с вариантом. Т.е. передать как параметр типа вариант в функцию


 
han_malign ©   (2015-03-26 11:43) [23]


> что варианты нельзя в VarType на равенство проверять, а надо по маске смотреть?

- дык там еще и varByRef - есть
а ссылка, массив и скаляр - это таки разные типы...


 
han_malign ©   (2015-03-26 11:47) [24]


> с одной стороны, это массив. С другой - вариант

- это массив вариантов...
или вы считаете, что varArray+varInteger - это не вариант?


 
junglecat ©   (2015-03-26 11:49) [25]

> или вы считаете, что varArray+varInteger - это не вариант?

почему же? по мне - так очень даже ничего вариант


 
имя   (2015-10-20 17:53) [26]

Удалено модератором


 
имя   (2015-10-20 20:38) [27]

Удалено модератором



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2017.08.27;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.002 c
2-1427276393
Ega23
2015-03-25 12:39
2017.08.27
Передача массива вариантов в функцию


2-1426143698
Atamali Memmedov
2015-03-12 10:01
2017.08.27
Exception


2-1431069430
Торри
2015-05-08 10:17
2017.08.27
Вопросы в переводе заголовочника с Си на Паскаль


4-1283494887
worldmen
2010-09-03 10:21
2017.08.27
Определение существования окна


15-1464608311
SergP
2016-05-30 14:38
2017.08.27
Передача параметров функции





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский