[gelöst] sets mit strings?

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
mulcheo
Beiträge: 57
Registriert: Do 1. Aug 2013, 15:11

[gelöst] sets mit strings?

Beitrag von mulcheo »

Hallo,

ich möchte prüfen, ob ein string in einer bestimmten Menge liegt. Leider fürt das zu endlos langen If (...) or ( ) or () Abfragen wie ...

Code: Alles auswählen

if (s = 'Giraffe') or (s = 'Affe') or (s = 'Maus') or (s = 'Tiger') then
ich würde gerne mit sets arbeiten aber

Code: Alles auswählen

if s in ['Affe','Maus', ... ]
geht leider nicht.

gibt es einen Workaround, der weniger Platz als if ()or()or()-Orgien einnimmt?
Zuletzt geändert von mulcheo am Di 30. Nov 2021, 10:08, insgesamt 1-mal geändert.

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: sets mit strings?

Beitrag von siro »

ich habe folgendes gefunden und ehrlich gesagt kannte ich das auch nicht.
In dem Link sind auch noch andere Möglichkeiten gezeigt.

https://forum.lazarus.freepascal.org/in ... c=37364.15

Code: Alles auswählen

Uses .....,StrUtils;  // wird zusätzlich benötigt für die Funktion AnsiIndexStr

var
  TT: array[0..3] of string = ('Giraffe', 'Affe', 'Maus','Tiger');
  T : String;

Operator in (const AText:string;const AValues: array of string):Boolean;
begin
  Result := AnsiIndexStr(AText,AValues) <> -1;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  T:='Affe';
  if (T in TT) then Caption:='Jo, is drin'; 
end;          
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Benutzeravatar
Lincoln Six Echo
Beiträge: 138
Registriert: Di 26. Aug 2014, 16:42
OS, Lazarus, FPC: Win10, Debian
CPU-Target: I7/I9/Q9650/u.a.
Wohnort: Hamburg

Re: sets mit strings?

Beitrag von Lincoln Six Echo »

Ganz einfach:

if pos('.mp3','.wav;.aac;.flac;.mp3') > 0 then

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: sets mit strings?

Beitrag von Socke »

Du kannst auch alles zu Programmstart in eine TStringList packen:

Code: Alles auswählen

var
  sl: TStringList; 
begin
  sl := TStringList.Create;
  sl.Duplicates := dupError;
  sl.Sorted := True; // Sorgt für eine schnellere, binäre Suche
  sl.Add('Giraffe');
  sl.Add('Affe');
  // ...
  
  // Abfrage
  if sl.IndexOf(s) <> -1 then
  // ...
end;
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Benutzeravatar
theo
Beiträge: 10468
Registriert: Mo 11. Sep 2006, 19:01

Re: sets mit strings?

Beitrag von theo »

Pos() ist wahrscheinlich die schlankeste Lösung, wenn es keine Überschneidungen mit Substrings gibt.

Mit TStringList könnte man es noch etwas näher am Wunsch des OP lösen:

Code: Alles auswählen

  SL:=TStringList.Create;
  SL.Sorted:=true;
  SL.StrictDelimiter:=true;
  SL.DelimitedText:='Giraffe,Affe,Maus,Tiger';
  if SL.IndexOf('Tiger')>-1 then ShowMessage('Tiger ist drin');
  SL.Free;

mulcheo
Beiträge: 57
Registriert: Do 1. Aug 2013, 15:11

Re: sets mit strings?

Beitrag von mulcheo »

hui, Danke für die Vorschläge, funktionieren super!
Pos() ist tatsächlich sehr schlank, da hätte ich eigentlich drauf kommen sollen, zumal ich den Befehl buchstäblich eine Zeile später im Quellcode habe...
Ich werde wohl zu Vorschlag #1 greifen, denke ich, weil mir die Idee gefällt, alles zentral in unter var bzw. const zu verwalten. Die Möglichkeit, Operatoren zu definieren kannte ich auch noch nicht; das gibt gleich Anlass zum Weiterlesen. Ich hoffe mal, StrUtils zerschiesst mir nicht etablierte Syntax, aber bis jetzt sieht alles gut aus.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: sets mit strings?

Beitrag von Winni »

Hi!

Sets geht nicht, wie schon beschrieben .

Aber seit einigen Version gibt es in case auch die Möglichkeit, mit strings zu arbeiten.
I love it. Und habe 30 Jahre darauf gewartet.

Code: Alles auswählen

var s : string;
...
case s of
'Affe' , 'Gieraffe': .....
'Bär', 'Himbär': ....
end;
Winni

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1432
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: sets mit strings?

Beitrag von fliegermichl »

Man kann sich die Strings auch vom FPC geben lassen:

Code: Alles auswählen

type
 TElement = (Affe, Giraffe, Loewe, Papagei);
 TElSet = set of TElement;

function isStringInSet(s : string; se : TElSet) : boolean;
var e : TElement;
     s1 : string;
begin
 Result := False;
 for e := Affe to Papagei do
 begin
  WriteStr(s1, e);
  if (AnsiCompareText(s, s1) = 0) then
  begin
   Result := True;
   exit;
  end;
 end;
end;

sstvmaster
Beiträge: 575
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.2.6
CPU-Target: 32+64bit
Wohnort: Dresden

Re: [gelöst] sets mit strings?

Beitrag von sstvmaster »

Oder mit IndexStr / IndexText.

Code: Alles auswählen

program Project1;

uses
  StrUtils;

var
  TElement: array[0..3] of string = ('Giraffe', 'AffE', 'Maus','Tiger');  // AffE mit großem E

begin
  //if IndexText('Affe', TElement) <> -1 then // The comparison is done case insensitively.
  if IndexStr('Affe', TElement) <> -1 then // Searches, observing case, for a string in an array of strings.
  begin
    WriteLn('gefunden');
  end
  else
  begin
    WriteLn('nicht gefunden');
  end;

  ReadLn;
end.
LG Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

Antworten