我使用来自DeCAL的DeCAL容器和Delphi6存储数据。键是一个字符串,它可以在映射中多次出现。
我想知道如何使用给定的键正确地迭代所有对象。
这个代码会:
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上迭代的最佳方法是什么呢?
发布于 2011-02-18 11:45:28
编辑:测试版本(我改变了以前使用的findif,因为我调查了它不使用快速定位,它只循环遍历所有项):
EDIT2:因为我以前的测试很糟糕,所以我编辑了函数以使它正常工作。它看起来与Name的答案几乎一样,但我更改了它,以避免混淆任何人与不正确的功能。
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;示例用法:
var
iter: DIterator;
iter := map.start;
while IterateOverFound(map, iter, ['abc']) do
begin
SetToValue(iter);
// get value
end;发布于 2011-02-18 11:32:09
同时,我做了一些研究,并找到了一个解决方案。由于DMultiMap是一个有序映射(基于黑色树而不是哈希值),所有具有相同键的项都被分组,以便下面的代码工作:
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;另一种可能是:
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;发布于 2011-02-21 09:00:57
我喜欢Linas提出的用法示例的语法,但是由于函数不能正常工作,下面是一个修正版本。FindIn不使用快速定位这一事实并不是一个问题,因为它只用于迭代(A DMultiMap是一个有序映射,因此所有具有相同键的项都在一起):
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;示例用法:
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;https://stackoverflow.com/questions/5040367
复制相似问题