Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 395
  • Last Modified:

How do I get access to a TStringList based on name

Hello,

I have the following:

var
Fruit, Meat : TStringList;
begin
Fruit := TStringList.Create;
Meat := TStringList.Create;
end;

and somewhere else I have

  if RetrieveAisle(ingredientname) = AisleName then
  begin
    AisleName.Add(ingredientname);
  end;

where RetrieveAisle is a function which returns a string.
The string will then be the name of the TStringList that I want to add the ingredient too.

I could go

if RetrieveAisle(ingredientname) = 'Fruit' then
begin
Fruit.Add(ingredientname);
end;

if RetrieveAisle(ingredientname) = 'Meat' then
begin
Meat.Add(ingredientname);
end;

but that is too sillly.
Anyone knows how to do this?

Ben
0
AivsCoder
Asked:
AivsCoder
2 Solutions
 
jimyXCommented:
The names of the variables will not be as you see them when your program is compiled.

Can you show the function details (what is ingredientname and what process you do to it inside your function so that you return string)?
0
 
MorphorCommented:
I don't know which action does the function perform but as it returns a string representation of a component (TStringList.Name):
FindComponent(StrR);

Open in new window

where StrR is a String, returns a component named StrR. For example
FindComponent('Fruit');

Open in new window

returns the component Fruit.

But if you want the component to "behave" like a TStringList, you have to tell the application to handle it as one:

TStringList(FindComponent('Fruit'));

Open in new window


So this should be what you're looking for:
TStringList(FindComponent(RetrieveAisle(ingredientname))).Add(ingredientname);

Open in new window

Of course, you have to modify the code because of security issues. For example:
...
var t: String;
begin
  t := RetrieveAisle(ingredientname);
  if t in ['Fruit', 'Meat'] then
    TStringList(FindComponent(t)).Add(ingredientname);
end;

Open in new window

0
 
epasquierCommented:
use a 'master' stringlist, that will hold the names of the lists along with their names.
You can do that because TStringList can match ONE object of any type with each text entry.

So :
Var
 MasterList:TStringList; 

Procedure InitMasterList;
begin
 MasterList:=TStringList.Create; 
 MasterList.Sorted:=True; // helps finding list quickly
 MasterList.Duplicates:=dupError; // do not allow duplicates names in master list
end;

Procedure ClearMasterList;
Var
 i:integer;
begin
 for i:=0 to MasterList.Count-1 do MasterList.Objects[i].Free;
 MasterList.Clear;
end;

Procedure FreeMasterList;
begin
 ClearMasterList;
 FreeAndNil(MasterList);
end;

// this function search a list in the master list, by its name
// if not found, it auto-creates it and return it to the caller.
// that particular implementation can be done differently, that 
// is only the way I usually do these kind of things.
// You could decide that it does not auto-create, or return the index
// of the list in the master, instead of the list itself.
// tell me if you want it otherwise.
Function FindOrCreateList(ListName:String):TStringList;
Var i:integer;
begin
 ListName:=UpperCase(ListName); // Always uppercase the list names, so 'Meat' and 'MEAT' refer to the same list
 i:=MasterList.IndexOf(ListName);
 if i>=0
  Then Result:=TStringList(MasterList.Objects[i]) // FOUND ! cast the object as a TStringList
  Else // NOT FOUND
   begin
    Result:=TStringList.Create; // Create a new list, that will be returned
  // optionally : sort all the lists (not master)
  // Result.Sorted:=True;  // help finding members quickly
    MasterList.AddObject(ListName,Result); // Add it to the MasterList with the associated name
   end;
end;

// how to find a list based on one of it's member, in the whole master
// WILL return the INDEX, just in case you are better interested in the NAME of the list.
function FindListHoldingMember(Member:String):Integer;
begin
 for Result:=0 to MasterList.Count-1 do
  begin
   if TStringList(MasterList.Objects[Result]).IndexOf(Member)>=0 Then Exit;
   // This will work only on EXACT match.
  end;
 Result:=-1; // This tells : NOT FOUND
end;

// Usage :
 i:=FindListHoldingMember('Apple');
 if i>=0 Then ShowMessage('Apple was found in '+MasterList[i]);

Open in new window

0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
AivsCoderAuthor Commented:
Hi there epasquier,

I like your code. Im not too sure if i'm right but you create a masterlist. Only one MasterList that is active. Every other list is temporarily created but not freed I think. My memory usage would be less.
Your code is better than my code which was creating a TStringList for each aisle. I have about 17 different aisle names so yeah if I only have to deal with one TStringList. That is good.  

I await for your reply. Thanks, Ben.

0
 
epasquierCommented:
Every other list is temporarily created but not freed I think.
No, not temporarily created. When I add a list to the masterlist, it is stored with it's logical name.
And it will remain there until you call ClearMasterList (or FreeMasterList). Ony then the lists referenced by the masterlist will be destroyed by this :
MasterList.Objects[i].Free;

Open in new window

(in ClearMasterList)

So you see, I create also one StringList per "aisle", but I only get to them through the MasterList, by its name. I have conveniently glued in the same function the search of a list by its name and the creation of a new aisle, given its name. Because generally when we need this kind of stuff, that's the best option :

FindOrCreateList('fruits').Add('Apple');
0
 
epasquierCommented:
Hi AivsCoder, do you still need some help on how to use this stuff ?
Otherwise, don't forget to close the question
0
 
AivsCoderAuthor Commented:
Thanks heaps, Ben
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now