[Webinar] Streamline your web hosting managementRegister Today

x
?
Solved

StringList Question!

Posted on 1999-12-14
27
Medium Priority
?
297 Views
Last Modified: 2010-04-06
Ok i have a stringlist with eg 10 items..

I have a Integer Counter that it will
say what position will get from the
string list and put them on the 4 labels.

eg.
When the Counter = 1 then it will update the labels with the values from the first 4 items of the StringList

Label1.caption := Stringlist.Strings[0];
Label2.caption := Stringlist.Strings[1];
Label3.caption := Stringlist.Strings[2];
Label4.caption := Stringlist.Strings[3];

When the Counter = 2 then it will update the labels with the values from the second 4 items of the StringList

Label1.caption := Stringlist.Strings[4];
Label2.caption := Stringlist.Strings[5];
Label3.caption := Stringlist.Strings[6];
Label4.caption := Stringlist.Strings[7];

etc...

any ideas ?

tryed this but didn't worked when the
Counter >= 3  

Label1.caption := Stringlist.Strings[Counter * 2 -1];
Label2.caption := Stringlist.Strings[Counter * 2];
Label3.caption := Stringlist.Strings[Counter * 2 +1];
Label4.caption := Stringlist.Strings[Counter * 2 +2];

=-(

Thanx
0
Comment
Question by:k6__
  • 5
  • 5
  • 4
  • +4
27 Comments
 
LVL 2

Author Comment

by:k6__
ID: 2282094
Edited text of question.
0
 
LVL 3

Expert Comment

by:philipleighs
ID: 2282179
Hi,

How about this small change. It assumes that Counter is zero based.


if Counter * 4 >= Stringlist.Count then
  raise Exception.Create('You need more items in the list.');
Label1.caption := Stringlist.Strings[Counter * 4];
Label2.caption := Stringlist.Strings[Counter * 4 + 1];
Label3.caption := Stringlist.Strings[Counter * 4 + 2];
Label4.caption := Stringlist.Strings[Counter * 4 + 3];


Cheers,
Phil.
0
 
LVL 5

Expert Comment

by:scrapdog
ID: 2282486
If your Counter is 1 based then substitute (Counter - 1) everywhere you see "Counter" in philipleighs' code.
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
LVL 1

Expert Comment

by:denizcan
ID: 2282631
Your code will work  for 3 but not more than 3, because it exceeds the count value of the StringList when Counter=4 and Counter * 2 + 2 = 10. Index values should be in the [0, Count -1] interval.
If your list has 10 items, so Count value is 10, than your index value should be lower than 10. If you add two more items to list, it will work for 4 also, but not 5.

if you explain with what algorithm your code should select the labels more than 3, I can correct your code...
0
 
LVL 5

Expert Comment

by:scrapdog
ID: 2282644
>I can correct your code...

but philipleighs already did that
0
 
LVL 5

Expert Comment

by:scrapdog
ID: 2282648
please read the comment history before you post as an answer
0
 
LVL 1

Expert Comment

by:denizcan
ID: 2282766
I had already read the comment history, and what philipleighs wrote was not enough, it would not work when even the Counter is 3!!!!

Pls, interpret before sending a warning...
0
 
LVL 1

Expert Comment

by:Fatman121898
ID: 2283560
I have an idea, but let me examine it.
Jo.
0
 
LVL 3

Expert Comment

by:philipleighs
ID: 2284364
>>
it would not work when even the Counter is 3!!!!
<<

Actually it will raise an exception saying 'You need more items in the list' if Counter is three.
This is obviously intentional.

You need to look a little closer.
0
 
LVL 1

Expert Comment

by:denizcan
ID: 2285308
What philipleighs did is not different than what TStringList does. TStringList also compares the Index value with Count value and raises exception. So the code

if Counter * 4 >= Stringlist.Count then
  raise Exception.Create('You need more
items in the list.');

is unnecessary...

Raising exception does not mean that the code works... Exceptions are used to debug the code...

I think, k6 needed to know why some exception messages were seen. What philipleighs did is only changing the exception message...

I had looked closer..
0
 
LVL 2

Author Comment

by:k6__
ID: 2285329
as i said i have a string list
with EG. 10 items.. it may have 200 or
324 or xxx items.. what i want is to
split it into Sections which each
section will contain eg 4 or 5 or x items... so i can easy get the items
of the section depending the counter.

eg if the counter is 1 then it will
get the first Section which contains
4 stringlist items..

First Section :
(StringList.Strings[0],  
 StringList.Strings[1],
 StringList.Strings[2]
 StringList.Strings[3])

2nd Section :
(StringList.Strings[4],  
 StringList.Strings[5],
 StringList.Strings[6]
 StringList.Strings[7])

3rd Section :
(StringList.Strings[8],  
 StringList.Strings[9])

0
 
LVL 1

Expert Comment

by:denizcan
ID: 2285387
than what we discussed until now is nonsense :)

var
  Section: Integer;
  Index: Integer;
  Count: Integer;
begin
  Index := (Section - 1) * 4;
  Count := StringList.Count;

  if Index < Count then Label1.Caption := StringList[Index] else Label1.Caption := '';

  Inc(Index);
  if Index < Count then Label2.Caption := StringList[Index] else Label2.Caption := '';

  Inc(Index);
  if Index < Count then Label3.Caption := StringList[Index] else Label1.Caption := '';

  Inc(Index);
  if Index < Count then Label4.Caption := StringList[Index] else Label4.Caption := '';

....

no exceptions or annoying messages...

Section starts from 1...

I use Count variable instead using StringList.Count to optimize the code, letter creates more code...

And use Inc Index Index + xxx, to avoid compiler to add-up each time some value to Index twice...

there is an alternative way  based on tag values which is more convenient.
0
 
LVL 3

Expert Comment

by:philipleighs
ID: 2285398
k6, check out the code at the bottom.

>>
You need to look a little closer.
<<

Hi Deniz, I was just being cheeky! ;-)

You say:
>>
Raising exception does not mean that the code works... Exceptions are used to debug the code...
<<
I don't agree with this at all. It that were so, then why would a function like ForceDirectories (and many many others) raise an exception if it failed. Surely it's not for debugging purposes. The main reason for it is that it relieves the programmer from checking the return value of every call.

Instead of

>>>
if not fileopen then
  result = false;  
  exit

if not fileread then
  closefile
  result = false;  
  exit

if not fileread then
  closefile
  result = false;  
  exit

fileclose
result = true  
<<<

You can have

>>>
fileopen
try
  fileread
  fileread
finally
  fileclose
end;
<<<

The caller would look like
>>>
if not ReadFileFunction then
  ShowError("Can't read file");
<<<

and

>>>
try
  ReadFileFunction
except
  ShowError("Can't read file");
end;
<<<

Program in C for a while and you'll appreciate exception handling.




OK k6, here's what I've got for you.

Have fun,

Cheers,
Phil.


function GetSectionItems(Strings: TStringList; SectionNumber: Integer; var a, b, c, d: string): Boolean;
begin
if SectionNumber * 4 >= Stringlist.Count then
  begin
    //Just for Deniz!  ;-)
    Result := false;
  end
else
  begin
    a := Stringlist.Strings[(SectionNumber - 1) * 4];
    b := Stringlist.Strings[(SectionNumber - 1) * 4 + 1];
    c := Stringlist.Strings[(SectionNumber - 1) * 4 + 2];
    d := Stringlist.Strings[(SectionNumber - 1) * 4 + 3];
    Result := true;
  end;
end;

Cheers,
Phil.
0
 
LVL 2

Author Comment

by:k6__
ID: 2285800
Well i found it! here it is :

 Var
  Counter,
  Counter2,
  Counter3,
  MyVar    : Integer;
 Begin
  Counter2 := 0; Counter3 := 0; MyVar := 2;
  For Counter := 0 To MyStringList.Count -1 Do
   Begin
    Inc(Counter2);
    If Counter2 = 4 Then
     Begin
      Counter2 := 0;
      Inc(Counter3);
      If Counter3 = MyVar Then
       Begin
        L01.Caption := MyStringList.Strings[Counter -3];
        L02.Caption := MyStringList.Strings[Counter -2];
        L03.Caption := MyStringList.Strings[Counter -1];
        L04.Caption := MyStringList.Strings[Counter];
       End;
     End;
   End;
 End;

So If i have a Multiple of 4 i wont have
any exceptions if it isn't then i have..
in this case i add TRY before LXX := MyStringLis.Strings[Counter -X] and
EXCEPT END; after it to avoid
error messages =)

SOOOO is there anything to optimize it or a better algorithm ?

Thanx!
0
 
LVL 2

Author Comment

by:k6__
ID: 2285821
Denizcan you code worked and it's well
optimized =))))) post it!!!

Thanx!
0
 
LVL 2

Author Comment

by:k6__
ID: 2285824
philipleighs you code won't work
if the last section contain items below
4 =(.
0
 
LVL 1

Expert Comment

by:Fatman121898
ID: 2285850
How about this:

procedure TForm1.ShowItems(var OutSL:TStringList;GroupNumber:Integer);
  const GroupSize=4;
  var InSL:TStringList;
      I:Integer;
begin
  InSL:=TStringList.Create;
  InSL.Clear;
  for I:=0 to GroupSize-1 do
    if (GroupNumber-1)*GroupSize+I<=OutSL.Count-1
      then  InSL.Add(OutSL.Strings[(GroupNumber-1)*GroupSize+I])
      else  InSL.Add('');
  Label1.Caption:=InSL[0];
  Label2.Caption:=InSL[1];
  Label3.Caption:=InSL[2];
  Label4.Caption:=InSL[3];
  InSL.Free;
end;


I've tested it, wokrs good.
Jo.
0
 
LVL 1

Expert Comment

by:denizcan
ID: 2286694
thanx k6

philipleighs, I do not need to work C a little...

In the past Microsoft had lots of problems with its codes. Then one of the maneger developed an error debugging tool. They used Assert macro to show exceptions...

I know sometimes exceptions can be used to show the user some msg. But they are usually for the programmers not users.

Example:
What does "Index out of range" mean for a user?

Instead a showing an exception message to user, I try to avoid them causing exceptions... Which one is better?

Example:
Think about an editor, which takes some values from a list, if the list is empty or nothing is selected in the list, I disable the editor...

thanx philipleighs, for discussion...
0
 
LVL 2

Expert Comment

by:florisb
ID: 2286738
reading the comment history I read somebody say... ... a bit too much I think. Isn't it just a simple mathematical trick:

function FillLabels(counter:integer) : boolean;
var
addToIndex,x : integer;
begin
addToIndex := (counter -1) * 4; //1->0, 2->4, 3->8, 4->12, et cetera.
try
Label1.caption := Stringlist.Strings[0+addToIndex];
Label2.caption := Stringlist.Strings[1+addToIndex];
Label3.caption := Stringlist.Strings[2+addToIndex];
Label4.caption := Stringlist.Strings[3+addToIndex];
result := true;
except
  begin
  showMessage('Out of index');
  result := false;
  end;
end; //try
end;
0
 
LVL 2

Expert Comment

by:florisb
ID: 2286740
And greetings offcourse,
Floris.

(hope I didn;t get the question wrond...;-)
0
 
LVL 3

Accepted Solution

by:
rickpet earned 200 total points
ID: 2286955
Ok guys where making this harder than it needs to be...


type
  TForm1 = class(TForm)
    Button1: TButton;
    ListBox1: TListBox;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }

  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}
type
  TMyRange = 0..9;
  TMySetRange = set of TMyRange;
var
  Counter: integer;
const
  Section1 = [0..3];
  Section2 = [4..7];
  Section3 = [8..9];

procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
function FindIndex(aSection: TMySetRange): integer;
var
  tmpSection: TMySetRange;
  i: integer;
begin
  tmpSection := aSection;
  for i:= low(TMyRange) to high(TMyRange) do
  begin
    if i in tmpSection then
      break;
  end;
  Result := i;
end;
begin

  Case Counter of
    0:  i:= FindIndex(Section1);
    1:  i:= FindIndex(Section2);
    2:  i:= FindIndex(Section3);
    else
      Counter := 0;
  end;
  if i < ListBox1.Items.Count then
    Label1.Caption := ListBox1.Items[i];
  if i+1 < ListBox1.Items.Count then
    Label2.Caption := ListBox1.Items[i+1];
  if i+2 < ListBox1.Items.Count then
    Label3.Caption := ListBox1.Items[i+2];
  if i+3 < ListBox1.Items.Count then
    Label4.Caption := ListBox1.Items[i+3];
  inc(Counter);
end;

end.
0
 
LVL 3

Expert Comment

by:rickpet
ID: 2286986
change
else  
 Counter := 0;
to...

else  
 Counter := -1;

Rick
0
 
LVL 3

Expert Comment

by:rickpet
ID: 2287234
hehe better way...

  Case Counter of
    0:  i:= FindIndex(Section1);
    1:  i:= FindIndex(Section2);
    2:  i:= FindIndex(Section3);
  end;
  if i < ListBox1.Items.Count then
    Label1.Caption := ListBox1.Items[i];
  if i+1 < ListBox1.Items.Count then
    Label2.Caption := ListBox1.Items[i+1];
  if i+2 < ListBox1.Items.Count then
    Label3.Caption := ListBox1.Items[i+2];
  if i+3 < ListBox1.Items.Count then
    Label4.Caption := ListBox1.Items[i+3];

  if Counter < 2 then
    inc(Counter)
  else
    Counter := 0;
0
 
LVL 1

Expert Comment

by:Fatman121898
ID: 2289050
k6,

did you ever read what I've posted ?
In my opinion it was the best solution of the problem. And most compact - no "case", just one "if".
But you are the judge, so you decide...

Jo.
0
 
LVL 5

Expert Comment

by:scrapdog
ID: 2289169
>But they are usually for the programmers not users.

The assumption that "all users are idiots" is a very good one.  And sometimes (no, always) there will be a user that is dumber than your intelligence (as a programmer), or your program's intelligence, could have possibly fathomed.  Catching exceptions is a relatively good way to mitigate the possible damage.  In some cases it will be even more efficient to use exception catching than to check for yourself...why reinvent the wheel in these cases?
0
 
LVL 3

Expert Comment

by:rickpet
ID: 2294946
Jo...

I think part of the problem with your solution is that if the numbers change he has to refigure

addToIndex := (counter -1) * 4; //1->0, 2->4, 3->8, 4->12, et

What happens if say...he find that in Section1 he only wants 3 labels, but in Section 2 he wants 5 labels updated...and Section 3 he wants 2...my solution works...it will in the future easier to implement and allow other programmers to change.

Yes right now yours does what it needs to..but it is very rigid and will break with any tinkering and will then have to be scrapped.  Working with sets is very intuitive and scales very well...

just my 2cents

Rick

0
 
LVL 2

Expert Comment

by:florisb
ID: 2295009
yeah, stop hiding; K6 and say something.....:-)

Or do we all have to defend outselves (fatman....:-)

F-)
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
This is an update to some code that someone else posted on Experts Exchange. It is an alternate approach, I think a little easier to use, & makes sure that things like the Task Bar will update.
There may be issues when you are trying to access Outlook or send & receive emails or due to Outlook crash which leads to corrupt or damaged PST file. To eliminate the corruption from your PST file, you need to repair the corrupt Outlook PST file. U…
The video will let you know the exact process to import OST/PST files to the cloud based Office 365 mailboxes. Using Kernel Import PST to Office 365 tool, one can quickly import numerous OST/PST files to Office 365. Besides this, the tool also comes…
Suggested Courses

612 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