Ast RTL: Map, Reduce, Where, Any
This commit is contained in:
@@ -254,6 +254,16 @@ type
|
||||
property TotalCount: Int64 read GetTotalCount;
|
||||
end;
|
||||
|
||||
TIndexSeries = class(TInterfacedObject, ISeries)
|
||||
private
|
||||
FIndexArray: TArray<Integer>;
|
||||
function GetCount: Int64;
|
||||
function GetTotalCount: Int64;
|
||||
function GetItems(Idx: Integer): TScalar;
|
||||
public
|
||||
constructor Create(const AIndexArray: TArray<Integer>);
|
||||
end;
|
||||
|
||||
TBinaryOperatorHelper = record helper for TBinaryOperator
|
||||
function ToString: string;
|
||||
end;
|
||||
@@ -1557,6 +1567,34 @@ begin
|
||||
Result := FTotalCount;
|
||||
end;
|
||||
|
||||
{ TIndexSeries }
|
||||
|
||||
constructor TIndexSeries.Create(const AIndexArray: TArray<Integer>);
|
||||
begin
|
||||
inherited Create;
|
||||
FIndexArray := AIndexArray;
|
||||
end;
|
||||
|
||||
function TIndexSeries.GetCount: Int64;
|
||||
begin
|
||||
Result := Length(FIndexArray);
|
||||
end;
|
||||
|
||||
function TIndexSeries.GetTotalCount: Int64;
|
||||
begin
|
||||
Result := GetCount;
|
||||
end;
|
||||
|
||||
function TIndexSeries.GetItems(Idx: Integer): TScalar;
|
||||
var
|
||||
sourceIndex: Integer;
|
||||
begin
|
||||
// The series maintains the "0 is newest" convention.
|
||||
// The index array was built from oldest to newest, so we access it in reverse.
|
||||
sourceIndex := FIndexArray[GetCount - 1 - Idx];
|
||||
Result := TScalar.FromInteger(sourceIndex);
|
||||
end;
|
||||
|
||||
initialization
|
||||
Assert(sizeof(TScalarValue) = 8);
|
||||
|
||||
|
||||
@@ -63,6 +63,8 @@ type
|
||||
|
||||
class function Defer(const Value: TDataValue; const Calc: TFunc): TDataValue; overload; static;
|
||||
|
||||
class function Map(const SourceSeries: ISeries; const MapperFunc: TFunc): ISeries; static;
|
||||
|
||||
class function FromRecordSeries(const AValue: IRecordSeries): TDataValue; static; inline;
|
||||
class function FromRecord(const [ref] AValue: TScalarRecord): TDataValue; static; inline;
|
||||
class function FromSeries(const AValue: ISeries): TDataValue; static; inline;
|
||||
@@ -79,7 +81,6 @@ type
|
||||
property Kind: TDataValueKind read GetKind;
|
||||
end;
|
||||
|
||||
type
|
||||
TDataValueKindHelper = record helper for TDataValueKind
|
||||
public
|
||||
function ToString: string;
|
||||
@@ -112,6 +113,18 @@ type
|
||||
constructor Create(const AVal: TScalar; const ACalc: TDataValue.TFunc);
|
||||
end;
|
||||
|
||||
TMapSeries = class(TInterfacedObject, ISeries)
|
||||
private
|
||||
FSourceSeries: ISeries;
|
||||
FMapperFunc: TDataValue.TFunc;
|
||||
// ISeries
|
||||
function GetCount: Int64;
|
||||
function GetTotalCount: Int64;
|
||||
function GetItems(Idx: Integer): TScalar;
|
||||
public
|
||||
constructor Create(const ASourceSeries: ISeries; const AMapperFunc: TDataValue.TFunc);
|
||||
end;
|
||||
|
||||
constructor TManagedLazy.Create(AKind: TDataValueKind; const AVal: IInterface; const ACalc: TDataValue.TFunc);
|
||||
begin
|
||||
inherited Create;
|
||||
@@ -329,6 +342,11 @@ begin
|
||||
Result := TDataValueKind(FKind);
|
||||
end;
|
||||
|
||||
class function TDataValue.Map(const SourceSeries: ISeries; const MapperFunc: TFunc): ISeries;
|
||||
begin
|
||||
Result := TMapSeries.Create(SourceSeries, MapperFunc);
|
||||
end;
|
||||
|
||||
function TDataValue.ToString: String;
|
||||
var
|
||||
sb: TStringBuilder;
|
||||
@@ -430,4 +448,40 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TMapSeries }
|
||||
|
||||
constructor TMapSeries.Create(const ASourceSeries: ISeries; const AMapperFunc: TDataValue.TFunc);
|
||||
begin
|
||||
inherited Create;
|
||||
FSourceSeries := ASourceSeries;
|
||||
FMapperFunc := AMapperFunc;
|
||||
end;
|
||||
|
||||
function TMapSeries.GetCount: Int64;
|
||||
begin
|
||||
Result := FSourceSeries.Count;
|
||||
end;
|
||||
|
||||
function TMapSeries.GetTotalCount: Int64;
|
||||
begin
|
||||
Result := FSourceSeries.TotalCount;
|
||||
end;
|
||||
|
||||
function TMapSeries.GetItems(Idx: Integer): TScalar;
|
||||
var
|
||||
sourceValue: TScalar;
|
||||
argArray: TArray<TDataValue>;
|
||||
mappedValue: TDataValue;
|
||||
begin
|
||||
// Get the original item, apply the mapper function, and return the result.
|
||||
sourceValue := FSourceSeries.Items[Idx];
|
||||
argArray := [TDataValue(sourceValue)];
|
||||
mappedValue := FMapperFunc(argArray);
|
||||
|
||||
if mappedValue.Kind <> vkScalar then
|
||||
raise EInvalidCast.Create('Map function did not return a scalar value.');
|
||||
|
||||
Result := mappedValue.AsScalar;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
Reference in New Issue
Block a user