RosettaCodeData/Task/Optional-parameters/Delphi/optional-parameters.pas

167 lines
3.3 KiB
ObjectPascal

program Optional_parameters;
{$APPTYPE CONSOLE}
uses
System.SysUtils;
type
TRow = TArray<string>;
TOrderingFun = TFunc<TRow, TRow, Boolean>;
TTable = array of TRow;
TRowHelper = record helper for TRow
public
procedure Swap(var other: TRow);
function ToString: string;
function Length: Integer;
end;
TTableHelper = record helper for TTable
private
procedure ExchangeRow(i, j: Integer);
public
procedure Sort(OrderingFun: TOrderingFun);
procedure Reverse;
function ToString: string;
end;
function Max(a, b: Integer): Integer;
begin
if a > b then
exit(a);
Result := b;
end;
{ TRowHelper }
function TRowHelper.Length: Integer;
begin
Result := System.Length(self);
end;
procedure TRowHelper.Swap(var other: TRow);
var
aLengthOther, aLengthSelf, aLength: Integer;
tmp: string;
i: Integer;
begin
aLengthOther := other.Length;
aLengthSelf := self.Length;
aLength := max(aLengthOther, aLengthSelf);
if aLength = 0 then
exit;
SetLength(self, aLength);
SetLength(other, aLength);
for i := 0 to aLength - 1 do
begin
tmp := self[i];
self[i] := other[i];
other[i] := tmp;
end;
SetLength(self, aLengthOther);
SetLength(other, aLengthSelf);
end;
function TRowHelper.ToString: string;
var
i: Integer;
begin
Result := '[';
for i := 0 to High(self) do
begin
if i > 0 then
Result := Result + ', ';
Result := Result + '"' + self[i] + '"';
end;
Result := Result + ']';
end;
{ TTableHelper }
procedure TTableHelper.ExchangeRow(i, j: Integer);
begin
Self[i].Swap(self[j]);
end;
procedure TTableHelper.reverse;
var
aLength, aHalfLength: Integer;
i: Integer;
begin
aLength := Length(self);
aHalfLength := aLength div 2;
for i := 0 to aHalfLength - 1 do
ExchangeRow(i, aLength - i - 1);
end;
procedure TTableHelper.Sort(OrderingFun: TOrderingFun);
var
i, j, aLength: Integer;
begin
if not Assigned(OrderingFun) then
exit;
aLength := Length(self);
for i := 0 to aLength - 2 do
for j := i + 1 to aLength - 1 do
if OrderingFun(self[i], self[j]) then
ExchangeRow(i, j);
end;
function TTableHelper.ToString: string;
var
i: Integer;
begin
Result := '[';
for i := 0 to High(self) do
begin
if i > 0 then
Result := Result + #10;
Result := Result + self[i].ToString;
end;
Result := Result + ']';
end;
function SortTable(table: TTable; Ordering: TOrderingFun = nil; column: Integer
= 0; reverse: Boolean = false): TTable;
var
acolumn: Integer;
begin
acolumn := column;
if not Assigned(Ordering) then
Ordering :=
function(left, right: TRow): Boolean
begin
Result := left[acolumn] > right[acolumn];
end;
table.Sort(Ordering);
if (reverse) then
table.reverse();
Result := table;
end;
var
data: TTable = [['a', 'b', 'c'], ['', 'q', 'z'], ['zap', 'zip', 'Zot']];
begin
Writeln(data.ToString, #10);
Writeln(SortTable(data).ToString, #10);
Writeln(SortTable(data).ToString, #10);
Writeln(SortTable(data, nil, 2).ToString, #10);
Writeln(SortTable(data, nil, 1).ToString, #10);
Writeln(SortTable(data, nil, 1, True).ToString, #10);
Writeln(SortTable(data,
function(left, right: TRow): Boolean
begin
Result := left.Length > right.Length;
end).ToString, #10);
Readln;
end.