Avatar billede pb1 Nybegynder
16. oktober 2008 - 14:19 Der er 8 kommentarer og
1 løsning

TStringlist duplicate count

Hej exp,

nogne der kan hjælpe mig med et stykke kode til optælning af duplicate items..

Jeg har en TStringList med noget data:

Ford
Ford
Ford
Mazda
Mazda
Volvo

ville gerne have det data fra Tstringlisten over i en ny, men ingen duplicates og antal af hvormange der var i den gamle liste.

Output:

Ford,3
Mazda,2
Volvo,1
Avatar billede martinlind Nybegynder
16. oktober 2008 - 15:14 #1
TStringlist har en property du kan sætte så du ikke har dups. hvis det er meget nødvendigt kan du muligvis bruge en af de events stringlisten har eller en try except til at tælle op hvilken en der var dup når du flytter over i den nye liste
Avatar billede pidgeot Nybegynder
16. oktober 2008 - 16:37 #2
Martin's forslag duer ikke hvis det er vigtigt at få at vide hvor mange der var (det lyder det til)

Hvilken udgave af Delphi sidder du med? Hvis det er 2009 ville jeg nok bruge en TDictionary til at tælle op i en løkke, og så tilføje strengene bagefter. Ellers ville jeg sortere listen, løbe den igennem mens jeg vedligeholder en tæller, og så tilføje en linje lige når jeg kan se ordet skifter.
Avatar billede pb1 Nybegynder
16. oktober 2008 - 20:46 #3
Jeg bruger delphi 7.
Ja, det er vigtigt får mig at vide hvormange der var.

har du evt et stykke kode til at sætte mig igang?
Avatar billede pidgeot Nybegynder
16. oktober 2008 - 21:09 #4
Nu er jeg ikke sikker, men MENER TStringList har en Sort - det går jeg ud fra hernede. Forudsætter ingen tomme strenge:

function CountDuplicates(oldStringList: TStringList): TStringList
var
  lastString:string;
  i,count:integer;
begin
  lastString := '';
  Result := TStringList.Create();
  for i := 0 to oldStringList.Count - 1 do begin
    if lastString <> '' and lastString <> oldStringList.Strings[i] then begin
      Result.Add(laststring+','+inttostr(count));
      count := 0;
    end;
    count := count + 1;
    lastString := oldStringList.Strings[i];
  end;
  Result.Add(laststring+','+inttostr(count));
end;

Utestet, forbehold for off-by-one fejl, syntaksfejl, etc.
Avatar billede pidgeot Nybegynder
16. oktober 2008 - 21:10 #5
...og der manglede selvfølgelig kaldet til oldStringList.Sort >_<

Den skal lige ind inden for-løkken.
Avatar billede hrc Mester
17. oktober 2008 - 01:32 #6
Denne algoritme kopierer fra en usorteret liste

procedure TfrmMain.MoveAndCount(aSource, aDestination: TStrings);
var
  List: TStringList;
  i, Index, Count: integer;
begin
  List := TStringList.Create;
  try
    List.Duplicates := dupIgnore;
    List.NameValueSeparator := ',';
    for i := 0 to aSource.Count - 1 do
    begin
      Count := 0;
      Index := List.IndexOfName(aSource[i]);
      if Index < 0 then
        List.Add(format('%s,%d',[aSource[i],Count]))
      else begin
        Count := StrToInt(List.ValueFromIndex[Index]) + 1;
        List.ValueFromIndex[Index] := IntToStr(Count);
      end;
    end;
    aDestination.Assign(List);
  finally
    List.Free;
  end;
end;
Avatar billede hrc Mester
17. oktober 2008 - 01:34 #7
Var lige en lille rettelse:

procedure TfrmMain.MoveAndCount(aSource, aDestination: TStrings);
var
  List: TStringList;
  i, Index: integer;
begin
  List := TStringList.Create;
  try
    List.Duplicates := dupIgnore;
    List.NameValueSeparator := ',';
    for i := 0 to aSource.Count - 1 do
    begin
      Index := List.IndexOfName(aSource[i]);
      if Index < 0 then
        List.Add(format('%s%s%d',[aSource[i],List.NameValueSeparator,1]))
      else
        List.ValueFromIndex[Index] := IntToStr(StrToInt(List.ValueFromIndex[Index]) + 1);
    end;
    aDestination.Assign(List);
  finally
    List.Free;
  end;
end;
Avatar billede pb1 Nybegynder
17. oktober 2008 - 18:02 #8
pidgeot laver du et svar.. din kode virker som den skal.. og du lavet det første svar..
Avatar billede pidgeot Nybegynder
17. oktober 2008 - 18:40 #9
Værsgo :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester