Solved

Compare contents of TStringLists?

Posted on 2001-06-20
18
441 Views
Last Modified: 2010-04-06
I have two  TStringlists.

  S : Integer;
  PlayList : TStringList;
  strList  : TStringList
.
.
.
  Randomize;
  S := Random(strList.Count);

  if S <= fileA then  begin
    PlayList.Add(strList[S]);
  end;

How can I perform this kind of check?

  if S {is within PlayList} then
     dothis
  else
     dothat
0
Comment
Question by:Dsys
  • 9
  • 8
18 Comments
 
LVL 6

Expert Comment

by:zebada
ID: 6212919
It doesn't make sense to compare S (an integer) to PlayList (a TStringList).

Or do you want to know if 0<=S<PlayList.Count ?

Or do you mean how can you find out if the value strList[S] is in playList then just use:

playList.IndexOf(strList[S]);

It will return -1 for not found or the index number of the first matching value if it is found.
0
 
LVL 5

Expert Comment

by:TheNeil
ID: 6213494
Nasty way would be to iterate through PlayList in a loop, checking each item. A better way is to try something like this (it is however case sensitive and only handles exact matches:

IF PlayList.IndexOf(S) <> -1
THEN
  //Item found
ELSE
  //Item NOT found

The Neil =:)
0
 

Author Comment

by:Dsys
ID: 6213820
can you show me the nasty way of testing by iterating through PlayList in a loop, checking each item...

i tried this:

//check
IF PlayList.IndexOf(strList[S]) <> -1 THEN
  load; //song has been played load new one.
else
  Play;

the if test always finds items in playlist even when it should not. See this code below gets run before the check.

//load
Randomize;
S := Random(strList.Count);
if S <= fileA then  begin
   PlayList.Add(strList[S]); //add one item.
end;
check;

playlist gets filled one item at a time. Where as strList is completely full of items at the begining. As playlist grows I want to skip items in it.
0
 
LVL 5

Expert Comment

by:TheNeil
ID: 6214147
Ok, try this:

  FUNCTION ItemInData(sValue : STRING; stlData ; TSTringList): BOOLEAN;
  VAR
    iCount : LONGINT;
  BEGIN
    Result := FALSE;
    FOR iCount := 0 TO (stlData.Count - 1)
    DO
      IF stlData[iCount] = sValue
      THEN
        Result := TRUE;
  END;

Then all you need to do is call the function in your IF statement:

IF ItemInData(S, PlayList)
THEN
  //Item found
ELSE
  //Item not found
 
This will check every item in the list with the item you want to search for. If it constantly returns TRUE (ie it finds it) then there must be a problem with the data in PlayList

The Neil =:)
0
 

Author Comment

by:Dsys
ID: 6216696
This does not work.

FUNCTION TfrmMain.ItemInData(sValue : STRING; stlData : TStringList): BOOLEAN;
VAR
   iCount : LONGINT;
BEGIN
   Result := FALSE;
   FOR iCount := 0 TO (stlData.Count - 1)  DO
     IF stlData[iCount] = sValue  THEN  <===Error in Line
       Result := TRUE;
END;

.
.
.
 IF ItemInData(inttostr(S), PlayList) THEN
    PickSong;


I have to compare the item number it could be items 1 to 10000. The number I compare is not a count, it is a list index number. That is why this always fails to find items in the list.
0
 

Author Comment

by:Dsys
ID: 6216840
This works better.

Function TfrmMain.ItemInData(sValue : String; stlData : TStringList): BOOLEAN;
Var
   i : LONGINT;
   x : String;
Begin
   Result := FALSE;
   For i := 0 To (stlData.Count - 1)  Do begin
     x := stlData[i];
     If x = strList[S]  Then
       Result := True;
   end;
end;

except when it gets to the last members of the list. Then the loop befome infinate. Might there be a way to end the loop if that becomes the case?
0
 
LVL 5

Expert Comment

by:TheNeil
ID: 6217233
This'll work better. It still loops through the data but it'll drop out as soon as it finds the item:

Function TfrmMain.ItemInData(s : LONGINT; stlData : TStringList): BOOLEAN;
VAR
  i : LONGINT;
  sItem : STRING;
BEGIN
  Result := FALSE;
  sItem := strList[S];
  i := 0;
  WHILE NOT(Result) AND (i < stlData.Count)
  DO
    IF stlData[i] = sItem
    THEN
      Result := True
    ELSE
      i := i + 1;
END;

Alternatively just go back to using IndexOf:

IF stlData.IndexOf(strList[S]) = -1
THEN
  //Not found
ELSE
  //Found

Being an idiot I didn't realise that S was an index into the list

The Neil =:)
0
 

Author Comment

by:Dsys
ID: 6218290
Cool... I will try this when I get home. The one other issue I ran into was this. When all items have been played and there for all songs are in playList, the check procedure becomes into an infinate loop.

I tried using a really stupid idea... using a global variable and incrementing it if the variable hit 2000 I figure that would be big enough to show that it is infinate, then I use an if statement to run application.terminate; This however does not really close the program gracefully. What do you think I should do?
0
 
LVL 5

Expert Comment

by:TheNeil
ID: 6218866
Why not just check to see if there are all the items in the playlist as there are in the track list? BUT, rather than checking each item, cheat and do this:

IF strList.Count = PlayList.Count
THEN
  //All items played

This of course assumes that a track will only be played once. If it can be played more than once then you need to check it using something like this:

FUNCTION AllItemsPlayed(stlPlayList, stlTrackList : TStringList): BOOLEAN;
VAR
  stlTemp : TStringList;
  iCount : LONGINT;
BEGIN
  Result := TRUE;
  stlTemp := TStringList.Create;
  TRY
    FOR iCount := 0 TO (stlPlayList.Count - 1)
    DO
      IF stlTemp.IndexOf(stlPlayList[iCount]) = -1
      THEN
        stlTemp.Add(stlPlayList[iCount]);

    Result := (stlTemp.Count = stlTrackList.Count);
  FINALLY
    stlTemp.Free;
  END;
END;

This is the same check but it makes sure that each item in the playlist only gets 'counted' once by creating a temporary list containing a single entry for each item

The Neil =:)
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:Dsys
ID: 6219715
Maybe it should write the contents of playlist out to a txt file? so that when the program is launched again it can load the txt file and continue to not repeat. when the list is full prompt to delete the file.
0
 
LVL 5

Accepted Solution

by:
TheNeil earned 50 total points
ID: 6221025
In that case just put the code to read the text file in the Create method of the form, and then write it out when the form is destroyed (OnDestroy). The code to do this isn't complex:

VAR
  sTemp : STRING;
  gFile : TEXT;
...
PlayList.Clear;
IF FileExists('c:\playlist.txt')
THEN
BEGIN
  AssignFile(gFile, 'c:\playlist.txt');
  Reset(gFile);
  WHILE NOT(EOF(gFile))
  DO
  BEGIN
    READLN(gFile, sTemp);
    IF sTemp <> ''
    THEN
      PlayList.Add(sTemp);
  END;
  CloseFile(gFile);
END;

IF <all tracks played>
THEN
  Playlist.Clear;

Then to save the play list:

AssignFile(gFile, 'c:\playlist.txt');
ReWrite(gFile);
FOR iCount := 0 TO (PlayList.Count - 1)
DO
  WRITELN(gFile, PlayList[iCount]);
CloseFile(gFile);

Simple as that (and if you pass the filename as a parameter then you can 'hide' it from the user)

The Neil =:)
0
 

Author Comment

by:Dsys
ID: 6221397
My internet is down... I will try this and let you know how it all goes, thank you for all your help.

0
 

Author Comment

by:Dsys
ID: 6222441
gFile : TEXT; <--- this line give and error. does it require a certain uses?

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;
0
 
LVL 5

Expert Comment

by:TheNeil
ID: 6223477
No, it's standard Pascal. Just move it to the global variable declarations and it should work fine

The Neil =:)
0
 

Author Comment

by:Dsys
ID: 6224202
ok.. works as global but the file does not get written with:

procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
var
  icount : integer;
begin

  AssignFile(gFile, 'c:\playlist.txt');
  ReWrite(gFile);
  FOR iCount := 0 TO (PlayList.Count - 1) DO <-- says count =0 ?
    WRITELN(gFile, PlayList[iCount]);

  CloseFile(gFile);
end;
0
 
LVL 5

Expert Comment

by:TheNeil
ID: 6224262
Well the code SHOULD be working (and yes, the counter should run from 0 - Stringlists are zero based). Have you tried stepping through the code to see what is stored in the playlist? You're not doing something stupid like freeing the playlist before you reach this point are you?

The Neil =:)
0
 

Author Comment

by:Dsys
ID: 6224461
TheNeil,

No that is what I thought too. But I will work on it. I dont want to push this question too much further. You have been very helpful and I thank you!
0
 
LVL 5

Expert Comment

by:TheNeil
ID: 6224557
Anytime you want to bounce a question then just post it

The Neil =:)
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now