![]() |
TArray - Alternative zu SetLength(..) ?
Ich möchte ein Array erstellen, und das soll bitte x Stellen breit sein. Jeder vernünftige Mensch geht, bei bspw. fünf Stellen hin und sagt
Delphi-Quellcode:
Meine Motivation ist, dass ich gerne eine Kollektion (wie eine Liste) hätte, und die soll bitte direkt vom Start weg eine bestimmte Länge haben. Ja, man kann hingehen, und nacheinander die beliebige Menge an Elementen hinzufügen.
var
myArray: TArray<Boolean>; begin myArray := TArray<Boolean>.Create(); SetLength(myArray, 5); [...] end Wäre es nicht viel eleganter, wenn man "anonym" ein Array mit gleich einer bestimmten Länge erzeugen kann und das Parameter für dem Copy-Konstruktor nimmt?
Delphi-Quellcode:
Das ist schon nahe dran, allerdings muss ich hier die Elemente im Array alle einzeln auflisten. Ich suche also im Endeffekt einen "Konstruktor" für ein Array das mich nicht die Elemente einzeln auflisten lässt, sondern im Endeffekt nur ein
uses Spring.Collections;
var myBooleanList: IList<Boolean>; begin myBooleanList := TCollections.CreateList<Boolean>( TArray<Boolean>.Create(False, False, False, False, False) ); end;
Delphi-Quellcode:
macht- Also nur die Anzahl der mit Default-Wert initialisierten Elemente entgegennimmt.
SetLength(..)
Gibt es da was feines? |
AW: TArray - Alternative zu SetLength(..) ?
Bei einem TArray<T> brauchst du den Konstruktor doch gar nicht:
Delphi-Quellcode:
var
myArray: TArray<Boolean>; begin SetLength(myArray, 5); [...] end |
AW: TArray - Alternative zu SetLength(..) ?
Zitat:
wir wäre es mit
Delphi-Quellcode:
Ich dachte so machen das vernünftige Menschen... :stupid:
var
MyArray : Array[0..4] of Boolean; OK Spass beiseite. Kannst Du mal erklären wofür und was Du vor hast? Mavarik |
AW: TArray - Alternative zu SetLength(..) ?
Ich möchte eine Liste anlegen. Beispielsweise die Standard RTL-Liste
Delphi-Quellcode:
. Oder eine
System.Generics.Collections.TList
Delphi-Quellcode:
.
Spring.Collections.IList
Diese Liste soll vom Start weg 20 Einträge haben. Booleans, Floats, irgendwas. Das sieht dann so aus
Delphi-Quellcode:
Ich denke, das geht besser. Einer Liste kann man bspw. schön sagen "Füge alle Einträge dieses Arrays hinzu":
uses System.Generics.Collections;
const numItems: Integer = 20; stdItemValue: Integer = 0; var myList: TList<Integer>; itemNo: Integer; begin myList := TList<Integer>.Create(); for itemNo := 0 to Pred(numItems) do myList.Add(stdItemValue); end;
Delphi-Quellcode:
Und ich habe das Gefühl, in der Richtung lässt sich das arg zusammenkürzen. Wenn absolut feststeht, dass es immer fünf Elemente sind, kann ich, dank
uses System.Generics.Collections;
const numItems: Integer = 20; stdItemValue: Integer = 0; var myArray: TArray<Integer>; myList: TList<Integer>; itemNo: Integer; begin // Array erstellen und füllen myArray := TArray<Integer>.Create(); SetLength(myArray, numItems); for itemNo := 0 to Pred(numItems) do myArray[itemNo] := stdItemValue; // Liste aus Array erstellen myList := TList<Integer>.Create(); myList.AddRange(myArray); // Mit Spring.Collections.IList ginge auch // myList := TCollections.CreateList<Integer>(myArray); end;
Delphi-Quellcode:
ja schon den hier machen:
TArray<>
Delphi-Quellcode:
.
myList.AddRange( TArray<Integer>.Create(0, 0, 0, 0, 0) );
Ich hätte jetzt gerne eine Art
Delphi-Quellcode:
.
TArray<Integer>.Create(elementCount: Integer)
Die erste Idee war, einfach einen Record Helper für [Delphi]TArray<T>[/Delphi zu basteln, aber Helferklassen dürfen anscheinend nicht generisch sein. Während ich das hier tippe fiel mir die nie genutzte, nicht generische Klasse
Delphi-Quellcode:
aus
TArray
Delphi-Quellcode:
ein:
System.Generics.Collections
Wenn ich mir eine winzige Helferklasse mit
Delphi-Quellcode:
baue kann ich eigentlich schon relativ zufrieden sein. Jetzt kann ich einfach sagen
TArrayHelper = class helper for System.Generics.Collections.TArray
class function CreateArray<T>(const itemCount: Integer): TArray<T>; end;
Delphi-Quellcode:
bzw.
myList.AddRange( TArray.CreateArray<Integer>(12345) );
Delphi-Quellcode:
Genau das wollte ich. Auch wenn es schon an den Rand des noch komfortabel lesbaren kommt.
myList := TCollections.CreateList<Integer>( TArray.CreateArray<Integer>(5) );
|
AW: TArray - Alternative zu SetLength(..) ?
Zitat:
Damit ist das Anwendungsgebiet von Collections die Komponentenentwicklung. Um eine hohe Anzahl von Booleans speichersparend zu verwalten eignet sich die Klasse TBits. |
AW: TArray - Alternative zu SetLength(..) ?
Ich habe weder eine "hohe Anzahl", noch muss ich dringend Speicher sparen. Ist doch nicht verboten, seine Booleans in eine Liste zu packen?
|
AW: TArray - Alternative zu SetLength(..) ?
Delphi-Quellcode:
Ist zwar nur ein Array, aber immerhin.
Const
MyList : Array [0..4] Of Boolean = (false,true,false,true,false); |
AW: TArray - Alternative zu SetLength(..) ?
Zitat:
Delphi-Quellcode:
??
uses System.Generics.Collections;
TMyList<T> = class TList<T> ... constructor Create(T...; Elements : Integer) begin inherited Create(T...); for itemNo := 0 to Pred(Elements) do Add(X); end; |
AW: TArray - Alternative zu SetLength(..) ?
Zitat:
Delphi-Quellcode:
Aus dem Debugger:
var
MyList : TList<Boolean>; begin MyList := TList<Boolean>.Create; MyList.Capacity := 20; // jetzt sind 20 Elemente drin, in diesem Fall ist der Wert der Items gleich false MyList.Free; end;
Code:
MyList ((False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False), 0, Pointer($666A2C) as {System.Generics.Defaults}IComparer<System.Boolean>, (nil,nil), $2A42880)
|
AW: TArray - Alternative zu SetLength(..) ?
Günthers lustige Ratestunde.
|
AW: TArray - Alternative zu SetLength(..) ?
Herzlich Willkommen dazu.
Wie gesagt, ich wollte einfach nur anonym ein Array mit X Elementen haben. Bastel ich mir halt einfach selbst was an TArray dran. Dachte, da könnte es vielleicht schon so etwas geben. |
AW: TArray - Alternative zu SetLength(..) ?
Zitat:
Worin liegt der Nutzen eine Liste mit X Elementen "Müll" zu füllen? Entweder habe ich die Daten Statisch im Source als Const oder lese es aus einer Resource oder aus einer Datei/Datenbank... Lass einfach das Generics geraffel weg und nimm einen Fillchar... Mavarik |
AW: TArray - Alternative zu SetLength(..) ?
Danke für die gut gemeinte Hilfe.
Ich hätte einfach nur fragen sollen "Gibt es schon etwas, womit ich anonym ein Array mit einer bestimmten Länge erstellen kann?". Dann hätte jemand gesagt "Nö. Bau dir halt selber was.". Und dann wäre es das schon gewesen. |
AW: TArray - Alternative zu SetLength(..) ?
Zitat:
|
AW: TArray - Alternative zu SetLength(..) ?
Zitat:
|
AW: TArray - Alternative zu SetLength(..) ?
Das mit der
Delphi-Quellcode:
war ja nur ein Beispiel. Ein Array mit x Elementen wollte ich gerne haben um es irgendwo reinzustecken:
TList
Delphi-Quellcode:
Meine Frage war einfach nur, ob es so etwas schon gibt.
function gibArray<T>(const elementCount: Integer): TArray<T>;
begin SetLength(Result, elementCount); end; Auf jeden Fall vielen Dank an alle beteiligten! :-) |
AW: TArray - Alternative zu SetLength(..) ?
Zitat:
Zum Beispiel es einer Variable vom Typ TArray<T> zuweisen? Warum also nicht gleich
Delphi-Quellcode:
aufrufen?
SetLength(meinArray, 5)
Klar, das eine ist eine Funktion, die dir ein Array einer bestimmten Länge zurückliefert, was du rein theoretisch direkt an eine andere Methode übergeben kannst (wobei ich hierbei den Nutzen davon bezweifeln möchte, ein Array mit x Einträgen, die aber nicht befüllt sind, zu übergeben). Und das andere eine Methode mit einem var Parameter, der die Größe eines zuvor deklarierten dynamischen Arrays setzt. Darum die konkrete Frage, wozu du so etwas haben möchtest. Wie bereits gesagt, ich bezweifel den praktischen Nutzen, nur um es woanders hin übergeben zu können, wenn die Elemente ja alle "leer" (
Delphi-Quellcode:
) sind.
Default(T)
Kannst du ein praktisches Beispiel benennen, wo man ein dynamisches Array mit einer bestimmten Größe aber leeren Einträgen irgendwo by Value (also nicht als var, denn das geht ja nicht mit einem Result einer Funktion) übergeben sollte? P.S. Bei diesem Code kräuseln sich mit die Fußnägel hoch:
Delphi-Quellcode:
Besser:
var
myBooleanList: IList<Boolean>; begin myBooleanList := TCollections.CreateList<Boolean>( TArray<Boolean>.Create(False, False, False, False, False) ); end;
Delphi-Quellcode:
var
myBooleanList: IList<Boolean>; begin myBooleanList := TCollections.CreateList<Boolean>([False, False, False, False, False]); end; |
AW: TArray - Alternative zu SetLength(..) ?
Ob man etwas wirklich so machen "sollte" - Darüber werden wir uns im Endeffekt doch wieder streiten.
Ganz konkretes Beispiel: Ich möchte eine
Delphi-Quellcode:
haben.
Spring.Collections.IList<TIrgendeinTyp>
Bei
Delphi-Quellcode:
kann ich ein Array mit x Elementen angeben und meine Liste beinhaltet direkt diese Elemente.
TCollections.CreateList<>(const values: Array of TIrgendeinTyp)
Hier sind die meisten schon ausgestiegen, das sei ja totaler Quatsch und überhaupt. Vielleicht ist bei meinen Pillen etwas durcheinander gekommen, aber ich finde, das entfernt sich zu weit von der eigentlichen Frage und tut eigentlich auch überhaupt nichts zur Sache. Ja, ich kann einfach ein Array nehmen, SetLength() darauf machen und dieses Array jetzt da hineinstecken. Ich kann auch x mal Add() auf meiner Liste machen. Ich wollte mir einfach nur die Array-Variable bzw. die Zähl-Variable für das "x mal" sparen. Also einfach sagen
Delphi-Quellcode:
.
CreateList<TIrgendeinTyp>( TArray.createArray<TIrgendeinTyp>(35) );
Und das schmeckt sicher jedem anders. |
AW: TArray - Alternative zu SetLength(..) ?
Zitat:
|
AW: TArray - Alternative zu SetLength(..) ?
Ich komme wirklich nicht hinterher :?
Woran erkennst du das? Du kannst doch nicht riechen, wofür die Liste gut ist oder was ich damit mache. Oder etwa doch? :shock: |
AW: TArray - Alternative zu SetLength(..) ?
Als Liste sehe ich hier auch keinen Nutzen. Was eher irgendwo mal nützlich sein könnte, wäre sowas, wie
![]() ![]() Beides werde ich evtl noch bei
Delphi-Quellcode:
hinzufügen.
Spring.Collections.TCollections
|
AW: TArray - Alternative zu SetLength(..) ?
Zitat:
Tue ich ja auch. Ich bin glücklich. Und trotzdem kommen alle, und wollen mich in die Zwangsjacke stecken :-( |
AW: TArray - Alternative zu SetLength(..) ?
Zitat:
|
AW: TArray - Alternative zu SetLength(..) ?
Zitat:
Wieso, wenn man die Lösung weiß, diese verschweigen, nur weil man keinen überzeugenden Verwendungszweck genannt bekommt? Sehr verwirrend. Zitat:
|
AW: TArray - Alternative zu SetLength(..) ?
Viele Jahre sind seitdem vergangen, und ich blicke zurück auf mein TArray.Construct<T>(..) das ich mir nach dieser feurigen Diskussion hier wohl gebaut haben muss. Anwendungsfälle hatte ich in der Zwischenzeit viele, insbesondere für Tests.
Ich bereue nichts. |
AW: TArray - Alternative zu SetLength(..) ?
Zitat:
Gut, wenn man anfängt mittendrin Booleans einzufügen oder rauszulöschen, ohne einen Zusammenhang zu irgendwas, oder der Zusammenhang zu einer anderen unabhängigen Liste, dann würde mit eher der Gedanke zu sowas die einem TDictionary<Irgendwas,Boolean> schwelgen. PS: ![]() |
AW: TArray - Alternative zu SetLength(..) ?
Was genau Du willst kann ich leider auch nicht nachvollziehen, aber vielleicht geht das hier in deine Richtung.
Man könnte solche Initialisierungen evtl. so machen, und die eigentlichen Settings damit separat kapseln.
Delphi-Quellcode:
var
LVar1 : TWasAuchImmer; LVar2 : TWasAuchImmer; LVar3 : TWasAuchImmer; Init_FuerAufgabe1( LVar1 ); Init_FuerAufgabe2( LVar2 ); Init_FuerAufgabe3( LVar1 ); ... procedure Init_FuerAufgabe1( var AVar : TWasAuchImmer); begin if not Assigned( AVar ) then AVar := TWasAuchImmer.Create; AVar.Items.Clear; AVar.Items.Add( false ); AVar.Items.Add( true ); AVar.Items.Add( false ); AVar.Items.Add( false ); AVar.Items.Add( false ); end; procedure Init_FuerAufgabe2( var AVar : TWasAuchImmer); begin if not Assigned( AVar ) then AVar := TWasAuchImmer.Create; AVar.Items.Clear; AVar.Items.Add( false ); AVar.Items.Add( true ); AVar.Items.Add( false ); AVar.Items.Add( true); AVar.Items.Add( false ); end; procedure Init_FuerAufgabe3( var AVar : TWasAuchImmer); begin if not Assigned( AVar ) then AVar := TWasAuchImmer.Create; AVar.Items.Clear; AVar.Items.Add( true ); AVar.Items.Add( true ); AVar.Items.Add( false ); AVar.Items.Add( false ); AVar.Items.Add( false ); end; |
AW: TArray - Alternative zu SetLength(..) ?
Ich gebe nochmal ein Beispiel.
Ganz klassisch:
Delphi-Quellcode:
Mir war das zu lang. Ich wollte lieber so etwas haben:
procedure p();
var a, b: TArray<Single>; arrayIndex: Integer; begin SetLength(a, 100); for arrayIndex := Low(a) to High(a) do a[arrayIndex] := 10.0; SetLength(b, 50); for arrayIndex := Low(b) to High(b) do b[arrayIndex] := 20.0; ProcessData(a, b); end;
Delphi-Quellcode:
procedure p()
begin ProcessData( TArray.Construct<Single>(100, 10.0), TArray.Construct<Single>(50, 20.0) ); end; Ich bekam es. Und sah dass es gut war. Ende 😉 |
AW: TArray - Alternative zu SetLength(..) ?
Ja, im Grunde wäre es zu praktisch, wenn der Array-Helper im Delphi bereits eine Create-Methode hätte, wo man eine Länge mit optionaler Initialisierung angeben könnte.
Nach SetLength ist der neue Speicher mit 0 initialisiert, beim Boolean-Array macht ein FillChar mit 1 bzw. mit Ord(True) ganz viele True daraus.
Delphi-Quellcode:
oder
uses
AnsiStrings; procedure TForm1.FormCreate(Sender: TObject); var a: TArray<Single>; begin //SetLength(a, 100); //for i := Low(a) to High(a) do // a[i] := 10.0; SetLength(a, 100); Move(PAnsiChar(DupeString(#0#0' A', 100))^, a[0], 100*4); // oder FillChar für ByteTypen
Delphi-Quellcode:
:stupid:
SetLength(a, 100); for i := 0 to High(a) do a[i] := 10.0;
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:50 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz