Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Array über mit String als "Index"? (https://www.delphipraxis.net/169577-array-ueber-mit-string-als-index.html)

Pow3rus3r 30. Jul 2012 12:01

Array über mit String als "Index"?
 
hallo zusammen,

ich habe eine große Menge Daten, die ich in ein Array laden will, was z.B. so aussieht:

[0]: Name1, 5, 18, 24, 58
[1]: Name2, 4, 32, 55, 23
...

Dabei sind mir die "Namen" jederzeit bekannt und ich würde das Array gerne über die Datensatznamen ansprechen. normal muss ja immer die Zeilennummer des Array angegeben werden. Gibt es da evtl. eine Möglichkeit, das ganze ohne eine Schleife o.ä. zu realisieren?

Danke und Gruß
Thomas

Bernhard Geyer 30. Jul 2012 12:08

AW: Array über mit String als "Index"?
 
Schau dir mal das Values-Property von TStrings an.

Uwe Raabe 30. Jul 2012 12:56

AW: Array über mit String als "Index"?
 
TDictionary wäre auch eine Alternative.

s.h.a.r.k 30. Jul 2012 13:16

AW: Array über mit String als "Index"?
 
Himitsu hatte ein Hier im Forum suchenassoziatives Array glaub schon mal sowas geschrieben... Irgendwie über einen Record, soweit ich das weiß... Nur finde ich es gerade nicht.

Würde aber auch ein TDictionary empfehlen, nachdem du schon XE hast.

Pow3rus3r 30. Jul 2012 14:06

AW: Array über mit String als "Index"?
 
Mit Tstrings und TDictionary kann man aber nur einem String genau EINEN anderen Sting zuordnen, oder habe ich da jetzt was falsch verstanden?

Ich bräuchte irgendwie sowas, wie eine Datenbank, bei der ich sagen kann, ich will den gesamten Datensatz (bestehend aus mehreren Datenfeldern) mit dem namen "xy".

Alternativ könnte ich wohl einfach die Datensätze (also die Zahlen) in ein Array laden und dann TDictionary oder Tstrings nutzen, um den ID's des Arrays die Namen zuzuordnen. Wäre zwar etwas umständlich, aber wie es scheint die einzige Möglichkeit, oder?

alleinherrscher 30. Jul 2012 14:12

AW: Array über mit String als "Index"?
 
Und wenn du ein Array of Record machst und dir eine Suchfunktion schreibst, die aus dem Namen den Array-Index sucht. Dann kannst du immer auf den kompletten Datensatz zugreifen. Ist perfomancetechnisch vielleicht nicht das allerschnellste, aber müsste ausreichend sein.

Gruß, Michael

p80286 30. Jul 2012 14:17

AW: Array über mit String als "Index"?
 
vielleicht wäre es gut wenn Du Deine Daten etwas näher beschreiben würdest.
Schon it einer Stringlist und binärer Suche hättest Du eine recht schnelle Möglichkeit für
Code:
name1 = 1 2 3 4 55 66 77
name2 = 1234 34 12342 2 77
name3 = irgendeinwert
Tdictonary kenn ich nicht aber vom Hörensagen ist das a) schneller b) einfacher zu handhaben.

Gruß
k-H

Pow3rus3r 30. Jul 2012 14:37

AW: Array über mit String als "Index"?
 
Die Daten bestehen aus:
1.) Datensatzname
2.) 16 einzelnen Hexadezimalzahlen, die auch einzeln ansprechbar sein müssen

Bisher hatte ich alles in einem Array und dann mit einer Schleife nach dem gewünschten Datensatznamen gesucht. Aber das ist bei der Anzahl von Daten (ca. 400 Datensätze) schon recht Zeitintensiv.

jfheins 30. Jul 2012 14:43

AW: Array über mit String als "Index"?
 
Du kannst sowas:
Delphi-Quellcode:
record
  Name: String;
  Values: Array of Byte;
end;
in ein Array packen und dafür sorgen dass dieses sortiert ist und bleibt. Dann kannst du eine binäre Suche benutzen.

Zitat:

Zitat von Pow3rus3r (Beitrag 1176316)
Mit Tstrings und TDictionary kann man aber nur einem String genau EINEN anderen Sting zuordnen, oder habe ich da jetzt was falsch verstanden?

Du kannst deine ganzen Wert auch in eine Containerklasse packen, dann reicht das vollkommen.

p80286 30. Jul 2012 15:14

AW: Array über mit String als "Index"?
 
Zitat:

Zitat von Pow3rus3r (Beitrag 1176324)
Die Daten bestehen aus:
1.) Datensatzname
2.) 16 einzelnen Hexadezimalzahlen, die auch einzeln ansprechbar sein müssen

Was heißt einzeln ansprechbar?

Zitat:

Zitat von Pow3rus3r (Beitrag 1176324)
Bisher hatte ich alles in einem Array und dann mit einer Schleife nach dem gewünschten Datensatznamen gesucht. Aber das ist bei der Anzahl von Daten (ca. 400 Datensätze) schon recht Zeitintensiv.

wie denn das? 400 Datensätze waren für W95 vielleicht eine Herausforderung, mit einem halbwegs modernem Equipment ist das doch ruck zuck erledigt!?

Gruß
K-H

jaenicke 30. Jul 2012 15:53

AW: Array über mit String als "Index"?
 
Zitat:

Zitat von Pow3rus3r (Beitrag 1176324)
Die Daten bestehen aus:
1.) Datensatzname
2.) 16 einzelnen Hexadezimalzahlen, die auch einzeln ansprechbar sein müssen

Da ist ein TObjectDictionary mit einem String und einer Klasse darin am besten. Denn dann kannst du entweder nur einen einzelnen Wert ansprechen, klar, oder aber auch die Daten zu einem Datensatz einmal suchen und dann alle Werte dazu benutzen ohne erneut zu suchen.

Wobei bei der geringen Anzahl der Datensätze die Frage ist, ob man da nicht noch anders herangehen kann. Aber dafür fehlen detailliertere Informationen wie (und wie oft) auf die Daten zugegriffen wird.

Uwe Raabe 30. Jul 2012 23:09

AW: Array über mit String als "Index"?
 
Zitat:

Zitat von Pow3rus3r (Beitrag 1176324)
Die Daten bestehen aus:
1.) Datensatzname
2.) 16 einzelnen Hexadezimalzahlen, die auch einzeln ansprechbar sein müssen

Dann sähe die Deklaration etwas so aus:

Delphi-Quellcode:
type
  TDatensatz = array[0..15] of Integer; // oder auch 1..16, Byte, Word, String oder was auch immer

var
  Datenbank: TDictionary<string, TDatensatz>;

var
  gibHer: Integer;

begin
  // Zugriff auf Zeile "Name1", Wert 5
  gibHer := Datenbank['name1'][5];
end;

tgvoelker 30. Jul 2012 23:46

AW: Array über mit String als "Index"?
 
Zitat:

Zitat von Pow3rus3r (Beitrag 1176291)
hallo zusammen,

ich habe eine große Menge Daten, die ich in ein Array laden will, was z.B. so aussieht:

[0]: Name1, 5, 18, 24, 58
[1]: Name2, 4, 32, 55, 23
...

Dabei sind mir die "Namen" jederzeit bekannt und ich würde das Array gerne über die Datensatznamen ansprechen. normal muss ja immer die Zeilennummer des Array angegeben werden. Gibt es da evtl. eine Möglichkeit, das ganze ohne eine Schleife o.ä. zu realisieren?

Danke und Gruß
Thomas

Würde ich als Descendant von TStringList implementieren. Im Constructor Sorted auf True, Duplicates auf dupError und OwnsObjects auf True. Die Daten selber als Objekt implementieren (class of TObject). Wäre meiner Ansicht nach am streßfreiesten.

himitsu 31. Jul 2012 01:23

AW: Array über mit String als "Index"?
 
Nja, wozu eine TStringList misbrauchen, wenn es das Dictionary gibt?
Und dazu noch als Generic, wo man bei der TStingList ständig alles selber (unsicher) casten muß. (abgesehn davon, wenn man alles via AS casten würde)

Furtbichler 31. Jul 2012 05:06

AW: Array über mit String als "Index"?
 
TDictionary gibt es ja nur für neuere Delphi bzw. nicht für das alte Zeugs.

Ich habe nur BDS2006 und muss mir mit einer Hashmap helfen. die hier im Forum rumgeistert.

himitsu 31. Jul 2012 08:02

AW: Array über mit String als "Index"?
 
http://www.delphipraxis.net/132817-u...ler-e2506.html
Generics raus und dafür einen festen Typen verwendet ... da sollte es auch locker noch unter D2006 laufen können.

jaenicke 31. Jul 2012 08:06

AW: Array über mit String als "Index"?
 
Zitat:

Zitat von Furtbichler (Beitrag 1176391)
TDictionary gibt es ja nur für neuere Delphi bzw. nicht für das alte Zeugs.

Ich habe nur BDS2006 und muss mir mit einer Hashmap helfen. die hier im Forum rumgeistert.

THashedStringList gab es da ja schon.

tgvoelker 31. Jul 2012 08:17

AW: Array über mit String als "Index"?
 
Zitat:

Zitat von himitsu (Beitrag 1176384)
wozu eine TStringList misbrauchen

;) Viele Wege führen nach Rom.
Zitat:

Zitat von himitsu (Beitrag 1176384)
wenn es das Dictionary gibt?

Da gefallen mir die Haare nicht. Davon abgesehen habe ich irgendwann mal mit Turbo Pascal 4 angefangen, neue Sachen verwende ich nur, wenn die "alten" nicht funktionieren für eine Sache oder ein Jungspund etwas komisch mit einem Dictionary implementiert. Was der Bauer nicht kennt und so.

jaenicke 31. Jul 2012 09:19

AW: Array über mit String als "Index"?
 
Zitat:

Zitat von tgvoelker (Beitrag 1176411)
Zitat:

Zitat von himitsu (Beitrag 1176384)
wozu eine TStringList misbrauchen

;) Viele Wege führen nach Rom.

Ja, richtig. Nur ist es eben schon ein Unterschied, ob man auf einer Straße mit einem Großsteinpflaster oder auf einer asphaltierten Autobahn fährt. :lol:
Ich für meinen Teil nehme dann doch eher die Autobahn, es sei denn ich bin im Urlaub und will mir Zeit lassen.

tgvoelker 31. Jul 2012 12:07

AW: Array über mit String als "Index"?
 
Der Vergleich hinkt nicht nur, der lahmt. Der Vorteil eines TStringList-Descendants ist die Zuweisungskompatibilität zu Items von Listboxen, Comboboxen u.ä.

jaenicke 31. Jul 2012 12:23

AW: Array über mit String als "Index"?
 
Ich finde das passt genau. Eine TStringList ist für den Zweck sowohl beim Programmieren als auch zur Laufzeit langsamer (je nach Anwendung drastisch) und dazu noch umständlicher zu verwenden. Da holperts eben etwas.

tgvoelker 31. Jul 2012 12:35

AW: Array über mit String als "Index"?
 
Entschuldige, habe nochmal editiert, um zu präzisieren.

Ich habe nur einen einzigen Anwendungsfall, der auf den ersten Blick mit einem Dictionary einfacher lösbar ist, als mit einer TStringList - und das ist eine Optimierung, die ohne Anzeige abläuft und wo nur das ergebnis ausgegeben wird.

Pow3rus3r 31. Jul 2012 12:43

AW: Array über mit String als "Index"?
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1176380)
Dann sähe die Deklaration etwas so aus:

Delphi-Quellcode:
type
  TDatensatz = array[0..15] of Integer; // oder auch 1..16, Byte, Word, String oder was auch immer

var
  Datenbank: TDictionary<string, TDatensatz>;

var
  gibHer: Integer;

begin
  // Zugriff auf Zeile "Name1", Wert 5
  gibHer := Datenbank['name1'][5];
end;

Danke, das wäre genau das, was ich brauche. Leider habe ich Probleme beim füllen des Arrays und bekomme beim kompilieren immer den Fehler, dass die Typen für TDatensatz nicht zum Datentyp Array passt.

Ich versuche daas Dictionary gerade so zu füllen:
Datenbank.Add('Name1', 12,13,14,16);

kann ich das Dictionary so (oder so in der Art) füllen?

jaenicke 31. Jul 2012 13:01

AW: Array über mit String als "Index"?
 
Mal ein Beispiel (ohne Prüfung, ob der Wert existiert usw.):
Delphi-Quellcode:
type
  TExampleData = class
    Values: array of Integer;
    constructor Create(const AValues: array of Integer);
  end;

// ...

constructor TExampleData.Create(const AValues: array of Integer);
var
  i: Integer;
begin
  SetLength(Values, Length(AValues));
  for i := Low(AValues) to High(AValues) do
    Values[i] := AValues[i];
end;

// Verwendung:
var
  Demo: TObjectDictionary<string, TExampleData>;
  CurrentValue: Integer;
  CurrentData: TExampleData;
begin
  Demo := TObjectDictionary<string, TExampleData>.Create([doOwnsValues]);
  try
    Demo.Add('Test', TExampleData.Create([1, 3, 4, 7]));
    // einfachen Wert lesen
    ShowMessage(IntToStr(Demo['Test'].Values[1]));
    // alle Werte durchgehen
    for CurrentValue in Demo['Test'].Values do
      ShowMessage(IntToStr(CurrentValue));
    // mehrere Werte zu einem Key lesen
    CurrentData := Demo['Test'];
    ShowMessage(IntToStr(CurrentData.Values[1]));
    ShowMessage(IntToStr(CurrentData.Values[2]));
  finally
    Demo.Free;
  end;
end;

Neumann 31. Jul 2012 17:30

AW: Array über mit String als "Index"?
 
Warum nicht ein Clientdataset für solche Dinge nehmen? Lässt sich nach jedem Feld sortieren, man kann mit Locate einen Wert suchen, in einem DBGrid darstellen, Laden und Speichern.

Pow3rus3r 1. Aug 2012 10:01

AW: Array über mit String als "Index"?
 
Ich verzweifele gerade bei dem Versuch, die Lösung von Uwe Raabe zu füllen
Delphi-Quellcode:
type
  T_Kennung = array[0..16] of string;

public
  Tabelle: TDictionary<string, T_Kennung>;

const Daten: T_Kennung = ('Name1','0x01','0x02','0x03','0x04','0x05','0x06','0x07','0x08','0x09','0x10','0x11','0x12','0x13','0x14','0x15','0x16');

begin
  Tabelle.Create;
  Tabelle.Add('Name1', Daten);
  showmessage (Tabelle['Name'][1]);
end;
Beim Ausführen der Zeilen zwischen "begin" und "end" bekomme ich immer eine Zugriffsverletzung beim lesen von Adresse 0000000C

Klaus01 1. Aug 2012 10:06

AW: Array über mit String als "Index"?
 
Delphi-Quellcode:
Tabelle := TDictionary.create();
Grüße
Klaus

Pow3rus3r 1. Aug 2012 11:18

AW: Array über mit String als "Index"?
 
Zitat:

Zitat von Klaus01 (Beitrag 1176536)
Delphi-Quellcode:
Tabelle := TDictionary.create();
Grüße
Klaus

TDictionary: Undeklarierter Bezeichner.


Ich habe die "Generics.Collections" jedoch bei "uses" eingebunden. Habe ich evtl. noch irgendwas übersehen/vergessen?

Pow3rus3r 1. Aug 2012 11:34

AW: Array über mit String als "Index"?
 
mit TDictionary<string, T_Kennung>.create hats dann endlich geklappt :) Funktioniert so, wie es sollte. Danke!


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:54 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-2025 by Thomas Breitkreuz