首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Delphi中正确地迭代DMultiMap (DeCAL)的搜索结果?

如何在Delphi中正确地迭代DMultiMap (DeCAL)的搜索结果?
EN

Stack Overflow用户
提问于 2011-02-18 10:48:32
回答 3查看 270关注 0票数 2

我使用来自DeCALDeCAL容器和Delphi6存储数据。键是一个字符串,它可以在映射中多次出现。

我想知道如何使用给定的键正确地迭代所有对象。

这个代码会:

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

返回以'abc‘作为键的所有对象?还是会从第一个以'abc‘作为键的对象开始返回映射的所有对象?

编辑:刚刚测试过。它返回映射的所有对象,从第一个对象开始,以'abc‘作为键。那么,在abc上迭代的最佳方法是什么呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-02-18 11:45:28

编辑:测试版本(我改变了以前使用的findif,因为我调查了它不使用快速定位,它只循环遍历所有项):

EDIT2:因为我以前的测试很糟糕,所以我编辑了函数以使它正常工作。它看起来与Name的答案几乎一样,但我更改了它,以避免混淆任何人与不正确的功能。

代码语言:javascript
复制
    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;

示例用法:

代码语言:javascript
复制
var
  iter: DIterator;

  iter := map.start; 
  while IterateOverFound(map, iter, ['abc']) do
  begin
    SetToValue(iter);
    // get value
  end;
票数 1
EN

Stack Overflow用户

发布于 2011-02-18 11:32:09

同时,我做了一些研究,并找到了一个解决方案。由于DMultiMap是一个有序映射(基于黑色树而不是哈希值),所有具有相同键的项都被分组,以便下面的代码工作:

代码语言:javascript
复制
function IterateOverObjects(map: DMultimap);
var iter1, iter2: DIterator;
begin
  iter1 := map.locate(['abc']);
  if not AtEnd(iter1) then
  begin
    iter2 := map.upper_bound(['abc']);
    repeat
      // do something with the value...
      Advance(iter1);
    until equals(iter1, iter2);
  end;
end;

另一种可能是:

代码语言:javascript
复制
function IterateOverObjects(map: DMultimap);
var iter: DIterator;
begin
  iter := map.locate(['abc']);
  while IterateOver(iter) do
  begin
    SetToKey(iter);
    if (getString(iter) <> 'abc') then break;
    SetToValue(iter);
    // do something with the value...
  end;
end;
票数 1
EN

Stack Overflow用户

发布于 2011-02-21 09:00:57

我喜欢Linas提出的用法示例的语法,但是由于函数不能正常工作,下面是一个修正版本。FindIn不使用快速定位这一事实并不是一个问题,因为它只用于迭代(A DMultiMap是一个有序映射,因此所有具有相同键的项都在一起):

代码语言:javascript
复制
function IterateOverFound(Map: DMultiMap; var iter: DIterator; const obj: array of const): Boolean;
var bWasToKey: boolean;
begin
  if diIteration in iter.flags then
  begin
    advance(iter);
    bWasToKey := diKey in iter.flags;
    SetToKey(iter);
    iter := DeCAL.findIn(iter, DeCAL.getContainer(iter).finish, obj);
    if not bWasToKey then
      SetToValue(iter);
  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;

示例用法:

代码语言:javascript
复制
var
  map: DMultiMap;
  iter: DIterator;

map := DMultiMap.Create;
map.putPair(['aaa', 0]);
map.putPair(['def', 1]);
map.putPair(['abc', 2]);
map.putPair(['abc', 3]);
map.putPair(['def', 4]);
map.putPair(['abc', 5]);
map.putPair(['def', 6]);
iter := map.start;
while IterateOverFound(map, iter, ['abc']) do
begin
  // do something with the value...
end;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5040367

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档