Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Stringliste indexOfName IndexofValue (https://www.delphipraxis.net/203012-stringliste-indexofname-indexofvalue.html)

bernhard_LA 3. Jan 2020 13:42

Stringliste indexOfName IndexofValue
 
meine Stringliste hat folgenden Inhalt

key1=Value1
keyA=Value2
keyV=Value3
keyX=Value4

Ich möchte in meine Liste nur dann ein neues Paar "key=value" einfügen, wenn der value nicht schon exitiert.
StringList.IndexofName hilft mir nicht, eine Funktion IndexOfvalue würde ich benötigen

Gibt es hier schon etwas ?

Neutral General 3. Jan 2020 13:44

AW: Stringliste indexOfName IndexofValue
 
Ich weiß nicht wie das bei dir aussieht aber kannst du Key und Value nicht einfach tauschen?

Dalai 3. Jan 2020 13:52

AW: Stringliste indexOfName IndexofValue
 
Wie wär's mit Delphi-Referenz durchsuchenTStringList.Values? Ist der gesuchte Wert nicht vorhanden, gibt das einen Leerstring zurück. Sofern also deine Werte nicht leer sind, müsste das doch sein, was du suchst.

Grüße
Dalai

Neutral General 3. Jan 2020 13:53

AW: Stringliste indexOfName IndexofValue
 
Values gibt nur den Wert zu einem Key. Damit kriegt man nicht raus ob IRGENDEIN Key einen bestimmten Value hat.

bernhard_LA 3. Jan 2020 14:03

AW: Stringliste indexOfName IndexofValue
 
tauschen von Key und Value geht leider nicht muss mich hier an ein festes Ausgabeformat halten,
will halt eine Suche ob ein Substring vorhanden ist vor jedem Einfügen vermeiden, die Listen können sehr lang werden

Dalai 3. Jan 2020 14:06

AW: Stringliste indexOfName IndexofValue
 
Tja, eine simple Variante ist, eine Kopie der Funktion IndexOfName zu machen und sie zu einem IndexOfValue umzuarbeiten. Ob man das dann als Ableitung von TStrings/TStringList macht oder ob das auch als Helper möglich ist, weiß ich nicht (nie benutzt).

Grüße
Dalai

hoika 3. Jan 2020 14:06

AW: Stringliste indexOfName IndexofValue
 
Hallo,
Zitat:

muss mich hier an ein festes Ausgabeformat halten
Das mag für die Ausgabe stimmen, aber intern kannst du das doch umdrehen (eigene StringList).

Korrektur
Zitat:

nur dann ein neues Paar "key=value" einfügen, wenn der value nicht schon exitiert.
IndexOf("key=value")=-1 -> existiert noch nicht

Aso die ganz normale Suche benutzen.

Neutral General 3. Jan 2020 14:10

AW: Stringliste indexOfName IndexofValue
 
Zitat:

Zitat von hoika (Beitrag 1454379)
IndexOf("key=value")=-1 -> existiert noch nicht

Funktioniert nicht. Was ist wenn key2=value existiert? Das kannst du damit nicht abfragen.

Jumpy 3. Jan 2020 14:31

AW: Stringliste indexOfName IndexofValue
 
TDictionary verwenden?

Uwe Raabe 3. Jan 2020 15:30

AW: Stringliste indexOfName IndexofValue
 
Zitat:

Zitat von Neutral General (Beitrag 1454374)
Values gibt nur den Wert zu einem Key. Damit kriegt man nicht raus ob IRGENDEIN Key einen bestimmten Value hat.

Du könntest über alle Einträge iterieren und
Delphi-Quellcode:
ValueFromIndex
prüfen.

bernhard_LA 3. Jan 2020 16:34

AW: Stringliste indexOfName IndexofValue
 
bin jetzt hier gelandet :

Delphi-Quellcode:
Type     TStringlistHelper = class helper for TStringlist

           function IndexofValue( ValueStr : string) : Integer;
       
         end;

function TStringlistHelper.IndexofValue ( ValueStr : string) : Integer;
  var  i : Integer;
begin
    i := 0;
    repeat
        if ( Pos(ValueStr, self[i])>0 ) then
            begin
              Result := i;
              exit
            end;

        Inc(i);

    until i > Self.Count-1;

    if i > Self.Count-1 then Result := -1;

end;
gibt es bessere / schnellere Lösungen ?

Neutral General 3. Jan 2020 16:56

AW: Stringliste indexOfName IndexofValue
 
Zitat:

Zitat von bernhard_LA (Beitrag 1454385)
gibt es bessere / schnellere Lösungen ?

Ja: ValueFromIndex benutzen statt pos.
Edit: Und eine for-Schleife.. Es sei denn du willst es extra umständlich machen :P
Edit2:
Delphi-Quellcode:
function TStringlistHelper.IndexofValue(AValueStr : string): Integer;
var i : Integer;
begin
  Result := -1;
  for i:= 0 to Count-1 do
  begin
    if ValueFromIndex[i] = AValueStr then // StrUtils.AnsiSameText ggf falls Case-Insensitiv
    begin
      Result := i;
      break;
    end;
  end;
end;

hoika 3. Jan 2020 17:42

AW: Stringliste indexOfName IndexofValue
 
Hallo,
Pos('=Value2',StringList.DelimitedText) ?

Uwe Raabe 3. Jan 2020 18:49

AW: Stringliste indexOfName IndexofValue
 
Zitat:

Zitat von hoika (Beitrag 1454389)
Hallo,
Pos('=Value2',StringList.DelimitedText) ?

Das würde aber auch bei einem Eintrag 'Value22' anschlagen.

hoika 3. Jan 2020 19:12

AW: Stringliste indexOfName IndexofValue
 
Hallo,
hach ;)
Pos('=Value2;',StringList.DelimitedText+';') ?

mit ; als Delimiter

so ;)

Redeemer 3. Jan 2020 19:43

AW: Stringliste indexOfName IndexofValue
 
Zitat:

Zitat von bernhard_LA (Beitrag 1454385)
gibt es bessere / schnellere Lösungen ?

Schreit eigentlich nach
Zitat:

Zitat von Jumpy (Beitrag 1454381)
TDictionary verwenden?

und Ausgabe mit TStringBuilder.

freimatz 3. Jan 2020 20:11

AW: Stringliste indexOfName IndexofValue
 
z.B. ja.

Zitat:

Zitat von bernhard_LA (Beitrag 1454385)
gibt es bessere / schnellere Lösungen ?

Ja, fast alle die nicht TStringlist verwenden :wink:
Alle Lösungen mit TStringlist sind nur Murks. Allenfalls für die reine Ausgabe könnte man eine verwenden.
Meine 2ct

himitsu 8. Jan 2020 17:11

AW: Stringliste indexOfName IndexofValue
 
Zitat:

Zitat von Neutral General (Beitrag 1454386)
Zitat:

Zitat von bernhard_LA (Beitrag 1454385)
gibt es bessere / schnellere Lösungen ?

Ja: ValueFromIndex benutzen statt pos.

Der Witz ist, dass dein Code zwar "richtig" funktioniert, im Gegensatz zur ursprünglichen Schleife, da dort das POS irgendwas findet, auch X oder geb in xXx=Ergebnis.
Und der Code ist viel einfacher zu lesen, ist genauso schnell wie das normale IndexOfName,
aber es muß zwangsläufiger langsamer werden, als die einfache Pos-Variante. :stupid:

Also besser ja, aber schneller ne.

Original wurde im String (ganze Zeile) nur gesucht/verglichen,
während ValueFromIndex erstmal langsam einen neuen String erzeugt (Teil aus Zeile kopiert) und dort dann schneller den ganzen String richtig/vollsändig vergleicht.
:D

Zitat:

Zitat von Uwe Raabe (Beitrag 1454392)
Zitat:

Zitat von hoika (Beitrag 1454389)
Hallo,
Pos('=Value2',StringList.DelimitedText) ?

Das würde aber auch bei einem Eintrag 'Value22' anschlagen.

EndsStr statt Pos wäre hier fast richtiger, aber das würde auch
Delphi-Quellcode:
Ergebnis
in
Delphi-Quellcode:
xXx=abc=Ergebnis
finden, obwohl der Wert eigentlich
Delphi-Quellcode:
abc=Ergebnis
wäre.
Gut, wenn man ausschließt, dass dort ein
Delphi-Quellcode:
=
drin vorkommt, dann reicht EndsStr aus.
Man müsste also auch noch prüfen, sodass vor dem Gefundenen kein weiteres
Delphi-Quellcode:
=
vorkommt.

Ansonsten ist die "einfache" Lösung mit ValueFromIndex.


Tipp: eine Zweiphasensuche
Erst schnell mit EndsStr suchen und dann jeden gefundenen Eintrag nochmal "genauer" mit ValueFromIndex nachprüfen,
falls es unbedingt schnell sein muß, auch in einer StringListe.


Schneller geht es sonst nur mit einer Liste, wo Name und Value bereits getrennt in zwei Variablen gespeichert wurden,
am Besten noch, wenn die Liste gehasht und womöglich sogar sortiert wurde.

Koloss 8. Jan 2020 19:33

AW: Stringliste indexOfName IndexofValue
 
Diese Funktion reicht doch, das er sehr performant sein muss habe ich hier nicht heraus gelesen
Code:
function IsValueInStringList(strList: TStrings; Value: String): Boolean;
var
  i: integer;
begin
  Result := False;
  for i := 0 to strList.Count do
    if strList.ValueFromIndex[i] = Value then
    begin
      Result := true;
      break;
    end;
end;
Wenn man die TStrings als TStringList anlegt kann man auch davor strList.Sort verwenden.
Die TStrings sollten mit TStringList erstellt werden


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:46 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