AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Gibts eine schnelle TStringList mit Spalten?

Gibts eine schnelle TStringList mit Spalten?

Ein Thema von moelski · begonnen am 13. Sep 2010 · letzter Beitrag vom 14. Sep 2010
Antwort Antwort
Seite 3 von 3     123
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#21

AW: Gibts eine schnelle TStringList mit Spalten?

  Alt 13. Sep 2010, 15:29
Ist aber vermutlich nicht so performant wie eine Lösung mittels einfacher Liste ...
Um eine DB zu schlagen, muß Du eine DB-Ähnliche Struktur erstellen!...Da hast Du nur noch eine Chance mit handoptimierten Algorithmen und viiieel Assembler. Ob das den Aufwand lohnt?
Entschuldige, aber das ist Quatsch. So ziemlich jede interne (sortierte) Listenstruktur ist performanter als eine DB. Großartige Verrenkungen muss man noch nicht einmal anstellen: Eine sortierte Liste mit binary Search reicht vollkommen. Performancetechnisch total zerbröseln kann man jede DB mit einem Red-Black-Tree, einer Hashmap oder einer Kombination. Dafür muss man dann aber für jede Informationsabfrage einen neuen Algorithmus schreiben.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von Brainstalker
Brainstalker

Registriert seit: 9. Jan 2004
Ort: Berlin
176 Beiträge
 
Delphi 2009 Professional
 
#22

AW: Gibts eine schnelle TStringList mit Spalten?

  Alt 13. Sep 2010, 17:37
Also hier die versprochene Datei. Ist aber glaub ich nicht so besonders brauchbar für dich. Kein Save und Load, ich dachte ich hätte damals mehr implementiert.
Angehängte Dateien
Dateityp: pas AdvStringList.pas (891 Bytes, 29x aufgerufen)
Michael N.
Brainstalker
  Mit Zitat antworten Zitat
Neumann

Registriert seit: 6. Feb 2006
Ort: Moers
513 Beiträge
 
Delphi 11 Alexandria
 
#23

AW: Gibts eine schnelle TStringList mit Spalten?

  Alt 13. Sep 2010, 18:49
Hallo,

warum nicht ein ClientDataset benutzen? Kann Speichern, Lesen, man Sortierkriterien festlegen. Bei Daten in einer Tabelle ideal.

Gruß

Ralf
Ralf
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#24

AW: Gibts eine schnelle TStringList mit Spalten?

  Alt 13. Sep 2010, 19:08
Die Daten liegen aber in einem proprietären Stringformat vor. Natürlich kann man sie dann in ein CDS o.ä (z.b Memory Dataset) überführen.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#25

AW: Gibts eine schnelle TStringList mit Spalten?

  Alt 14. Sep 2010, 09:24
Ist aber vermutlich nicht so performant wie eine Lösung mittels einfacher Liste ...
Um eine DB zu schlagen, muß Du eine DB-Ähnliche Struktur erstellen!...Da hast Du nur noch eine Chance mit handoptimierten Algorithmen und viiieel Assembler. Ob das den Aufwand lohnt?
Entschuldige, aber das ist Quatsch. So ziemlich jede interne (sortierte) Listenstruktur ist performanter als eine DB. Großartige Verrenkungen muss man noch nicht einmal anstellen: Eine sortierte Liste mit binary Search reicht vollkommen. Performancetechnisch total zerbröseln kann man jede DB mit einem Red-Black-Tree, einer Hashmap oder einer Kombination. Dafür muss man dann aber für jede Informationsabfrage einen neuen Algorithmus schreiben.
Okay geschenkt, ich war zu "Listenfixiert". Aber was bitte ist ein "Red-Black-Tree"? (der Wikipediaartikel ist mir zu farblastig). Mir sind nur die "Nil"-Blätter aufgefallen.

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Satty67

Registriert seit: 24. Feb 2007
Ort: Baden
1.566 Beiträge
 
Delphi 2007 Professional
 
#26

AW: Gibts eine schnelle TStringList mit Spalten?

  Alt 14. Sep 2010, 09:33
In C# bin ich dabei mit ein ObjectTable als Basis für ein nachgebautes StringGrid zu entwerfen. Das ist genauso leicht in Delphi realisierbar.

Es ist im Prinzip eine einfach Klasse mit dem Member
FObjectColumns = array of TObjectList; .
auf Strings spezialisiert könnte man
FStringColumns = array of TStringList nehmen.

Dabei ist jede Spalte eine TStringlist, lässt sich sehr einfach verwalten und um weitere Spalten erweitern. Zugriff erfolgt wie bei StringGrid via
Delphi-Quellcode:
function Cell(row, column : Integer): String;
begin
  sl := FStringColumns[column];
  result := sl[row];
end;
Also zumindest eine Basis-Funktionalität mit Get/SetCell und dynamischer Anpassung der Reihen/Spalten ist recht fix gemacht

PS: Wenn es interessant ist, kann ich heute Abend schnell eine Basisklasse schreiben, die Logik kann ich ja aus dem fertigen Code in C# übernehmen und muss nicht mehr viel dabei denken...
  Mit Zitat antworten Zitat
Benutzerbild von mleyen
mleyen

Registriert seit: 10. Aug 2007
609 Beiträge
 
FreePascal / Lazarus
 
#27

AW: Gibts eine schnelle TStringList mit Spalten?

  Alt 14. Sep 2010, 09:41
Also zumindest eine Basis-Funktionalität mit Get/SetCell und dynamischer Anpassung der Reihen/Spalten ist recht fix gemacht

PS: Wenn es interessant ist, kann ich heute Abend schnell eine Basisklasse schreiben, die Logik kann ich ja aus dem fertigen Code in C# übernehmen und muss nicht mehr viel dabei denken...
Das Problem ist aber SaveToFile / LoadFromFile ohne Delim zu implementieren.
Der Rest ist echt einfach:
property Strings[const Row, Col: Integer]: string read getStrings write setStrings; + GetCol(ColId): StringList + Add/DelCol(ColId)
  Mit Zitat antworten Zitat
Satty67

Registriert seit: 24. Feb 2007
Ort: Baden
1.566 Beiträge
 
Delphi 2007 Professional
 
#28

AW: Gibts eine schnelle TStringList mit Spalten?

  Alt 14. Sep 2010, 10:09
SaveToFile denke ich ist einfach, eine CSV Struktur genauso wie eine PlainText-Struktur. (Müssen ja nur die Spalten einer Reihe entsprechend kombiniert werden)

Eher das LoadFromFile, wenn keine Delimiter oder CSV Struktur vorhanden ist. Aber das Problem einer Einleselogik hat er ja dann immer und muss gelöst werden, sonst braucht man gar kein Container mit Spalten dafür zu suchen.

Edit: So, habe mal etwas gebastelt (bzw. eine angefangene C# Klasse umgeschrieben)

Das wechsen zw. den Sprachen überfordert mich, hatte jetzt dann keinen Nerv mehr (=/:=/==/" "/' ') macht mich verrückt

Cell ist zero-based wie beim StringGrid. Row/ColCount muss man nicht setzen, passt sich dynamisch an. Nur zu Abfrage oder wenn man die Tabelle zum Speicher sparen reduzieren will aufzurufen. Ist nur eine Basis, also Fehlerbehandlung und Endfunktionalität soll reinmachen, wer es benutzen möchte!
Delphi-Quellcode:
unit UStringTable;

interface

uses
  Classes;

type
  TStringTable = class
  private
    FTableColumns : array of TStringList;
    FDelimiter : String;
    FBoundary : String;
    FCrNlScheme : String;

    function GetCell(Row, Col: Integer): String;
    function GetColCount: Integer;
    function GetRowCount: Integer;
    procedure SetCell(Row, Col: Integer; const Value: String);
    procedure SetColCount(const Value: Integer);
    procedure SetRowCount(const Value: Integer);
    function GetCSV: String;
    procedure SetCSV(const Value: String);

  public
    constructor Create;
    destructor Destroy; override;

    procedure Clear;
    function CSVtoFile(Filepath : String): Integer;

    property Delimiter : String Read FDelimiter Write FDelimiter;
    property Boundary : String Read FBoundary Write FBoundary;
    property CrNlScheme : String Read FCrNlScheme Write FCrNlScheme;

    property Cell[Row, Col: Integer]: String Read GetCell Write SetCell;
    property RowCount : Integer Read GetRowCount Write SetRowCount;
    property ColCount : Integer Read GetColCount Write SetColCount;
    property CSV : String Read GetCSV Write SetCSV;
  end;

implementation

{ TStringTable }

constructor TStringTable.Create;
begin
  FDelimiter := ',';
  FBoundary := '"';
  FCrNlScheme := #13#10;
end;

destructor TStringTable.Destroy;
begin
  self.Clear;
  inherited;
end;

procedure TStringTable.Clear;
var
  i : Integer;
begin
  for i := 0 to Length(FTableColumns) -1 do
    FTableColumns[i].Free;
  SetLength(FTableColumns, 0);
end;

function TStringTable.GetColCount: Integer;
begin
  Result := length(FTableColumns);
end;

procedure TStringTable.SetColCount(const Value: Integer);
var
  i, j : Integer;
begin
  if Value < 0 then Exit;

  while (self.ColCount > Value) do
  begin
    i := Length(FTableColumns) - 1;
    FTableColumns[i].Free;
    SetLength(FTableColumns, i);
  end;

  while (self.ColCount < Value) do
  begin
    i := Length(FTableColumns);
    SetLength(FTableColumns, i + 1);
    FTableColumns[i] := TStringList.Create;
    // set new Column to current RowCount
    for j := 0 to self.RowCount -1 do
      FTableColumns[i].Add('');
  end;
end;

function TStringTable.GetRowCount: Integer;
begin
  if (Length(FTableColumns) > 0) then
    Result := FTableColumns[0].Count
  else
    Result := 0;
end;

procedure TStringTable.SetRowCount(const Value: Integer);
var
  i : Integer;
begin
  if Value < 0 then Exit;

  while (self.RowCount > Value) do
  begin
    for i := 0 to self.ColCount -1 do
      FTableColumns[i].Delete(self.ColCount -1);
  end;

  while (self.RowCount < Value) do
  begin
    for i := 0 to self.ColCount -1 do
      FTableColumns[i].Add('');
  end;
end;

function TStringTable.GetCell(Row, Col: Integer): String;
begin
  Result := FTableColumns[Col][Row];
end;

procedure TStringTable.SetCell(Row, Col: Integer; const Value: String);
begin
  if (Col >= self.ColCount) then
    self.ColCount := Col + 1;
  if (Row >= self.RowCount) then
    self.RowCount := Row + 1;

  FTableColumns[Col][Row] := Value;
end;

function TStringTable.GetCSV: String;
var
  r, c, rCount, cCount : Integer;
begin
  Result := '';
  rCount := self.RowCount;
  cCount := self.ColCount;

  for r := 0 to rCount -1 do
  begin
    for c := 0 to cCount -1 do
    begin
      Result := Result +
                FBoundary +
                self.Cell[r, c] +
                FBoundary;
      if (c < (cCount - 1)) then
        Result := Result + FDelimiter;
    end;
    if (r < (rCount -1)) then
      Result := Result + FCrNlScheme;
  end;
end;

procedure TStringTable.SetCSV(const Value: String);
begin
  // ToDo...
end;

function TStringTable.CSVtoFile(Filepath: String): Integer;
begin
  // ToDo...
  Result := 0; // returns last Win32 Error
end;

end.
.
Füllen mit 10.000.000 String-Felder â 10 Zeichen Länge dauert 3 Sekunden, denke das ist ganz brauchbar. GetCSV reichte mir erstmal, um das Ergebnis bzw. den Inhalt der Tabelle zu testen

Geändert von Satty67 (14. Sep 2010 um 21:08 Uhr) Grund: Typo, wie immer...
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:43 Uhr.
Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf