Hi I'm using Delphi and I have a StringList with this items:
45
A15
015
A15
A15
45
I want to process it and make a second stringlist that will have the number of appearance of each element:
45 [2]
015 [1]
A15 [3]
How can I do this with Delphi?
The tally or frequency count is the calculation of how many people fit into a certain category or the number of times a characteristic occurs. This calculation is expressed by both the absolute (actual number) and relative (percentage) totals.
You could use a dictionary:
Frequencies := TDictionary <String, Integer>.Create;
try
// Count frequencies
for Str in StringList do
begin
if Frequencies.ContainsKey (Str) then
Frequencies [Str] := Frequencies [Str] + 1
else
Frequencies.Add (Str, 1);
end;
// Output results to console
for Str in Frequencies.Keys do
WriteLn (Str + ': ' + IntToStr (Frequencies [Str]));
finally
FreeAndNil (Frequencies);
end;
The only problem might be that the order in which the results appear is completely random and dependes on the inner working of the hash map.
Thanks to daemon_x for the full unit code:
program Project1;
{$APPTYPE CONSOLE}
uses SysUtils, Classes, Generics.Collections;
var Str: String;
StringList: TStrings;
Frequencies: TDictionary <String, Integer>;
begin
StringList := TStringList.Create;
StringList.Add('45');
StringList.Add('A15');
StringList.Add('015');
StringList.Add('A15');
StringList.Add('A15');
StringList.Add('45');
Frequencies := TDictionary <String, Integer>.Create;
try
// Count frequencies
for Str in StringList do
begin
if Frequencies.ContainsKey (Str) then
Frequencies [Str] := Frequencies [Str] + 1
else
Frequencies.Add (Str, 1);
end;
// Output results to console
for Str in Frequencies.Keys do
WriteLn (Str + ': ' + IntToStr (Frequencies [Str]));
finally
StringList.Free;
FreeAndNil(Frequencies);
end;
end.
Sort the original list,
list1.sort;
create a new list
list2:=TStringList.Create;
iterate over the sorted list to count every different item and store the a count in the objects field of the resulting list (or if you don't use it already, just typecast the count into a pointer and store it as the object).
previtem:=list1[0];
count:=1;
for i:=1 to list1.count-1 do
begin
if list1[i]=previtem then
inc(count)
else
begin
list2.addObject(previtem,pointer(count));
previtem:=list1[i];
count:=1;
end;
end;
list2.addObject(previtem,pointer(count));
finally, iterate again to add the count to the string
for i:=0 to list2.count-1 do
list2.items[i]:=list2[i]+' ['+inttostr(list2.objects[i])+']';
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With