Search code examples
delphidecal

How to iterate properly over the search results of a DMultiMap (DeCAL) in Delphi?


I am using the DMultiMap container from DeCAL with Delphi 6 to store data. The key is a string which can appears several time in the map.

I wonder how to iterate properly over all objects with a given key.

Will this code:

function IterateOverObjects(map: DMultimap);
var iter: DIterator;
begin
  iter := map.locate(['abc']);
  while IterateOver(iter) do
  begin
    // do something with the value...
  end;
end;

returns all the objects of with 'abc' as key? Or will it returns all the objects of the map starting from the first object with 'abc' as key?

Edit: Just tested. It returns all the objects of the map starting from the first object with 'abc' as key. What is then the best way to iterate over 'abc'?


Solution

  • EDIT: tested version (I've changed previously used findif, because I investigated that it doesn't use fast locate, it just loops through all the items):

    EDIT2: because my previous test was bad, I've edited function to make it work properly. it looks almost the same as Name's answer, but I changed it to not confuse anyone with incorrect function.

        function IterateOverFound(Map: DMultiMap; var iter: DIterator; const obj: array of const): Boolean;
    begin
      if diIteration in iter.flags then
      begin
        advance(iter);
        SetToKey(iter);
        iter := findIn(iter, Map.finish, obj);
      end
      else
      begin
        iter := Map.locate(obj);
        Include(iter.flags, diIteration);
      end;
    
      Result := not atEnd(iter);
      if not result then
        Exclude(iter.flags, diIteration);
    end;
    

    Example usage:

    var
      iter: DIterator;
    
      iter := map.start; 
      while IterateOverFound(map, iter, ['abc']) do
      begin
        SetToValue(iter);
        // get value
      end;