Re: How to use associative arrays in Ada 2005?



Georg Bauhaus <bauhaus@xxxxxxxxxxxxx> writes:

I think that in this case the Ada.Containers requirement
of being minimal building blocks applies.

Right, the library is designed to be composable. Here's a case where a
container needs to contain another container.


If the elements in a map are containers themselves (or are
otherwise big), you may want to use Update_Element.

Right. Use Insert to create the element in the outer container, and then use
Update_Element to manipulate the inner container.


That is in order to manipulate one of the 2nd level maps,
you could either:

Ouch! A lot of copying here...

Or,

- Get a cursor for the element at key "family name".
- Define a subprogram that manipulates the 2nd level map
(the one containing "name" as key).
- Call Update_Element with the cursor and the subprogram.

Right, this is the correct approach.


Ages : Str_Map_Maps.Map; -- That's the "hash of a hash"
Named_Age: Str_Int_Maps.Map;

You don't need the Named_Age map. There's a version of Insert that accepts
just a key (which is different from the other versions, which accept both key
and element).


procedure Set_Age(name: String; value: in out Str_Int_Maps.Map) is
begin
Named_Age.Include("name", Age); -- Note how `Age` is used here

Here you can just say:
Value.Include ("name", Age);

end Set_Age;


begin
Ages.Insert("family name", Named_Age);

It's probably better to use the insert that returns a cursor, and then reuse
that cursor value, since that will obviate the need for a separate Find.

You can also eliminate the Name_Age map object, if you use the Insert that
accepts a key only. (If the key doesn't already exists, then it inserts an
element with a default value. Here that would mean an empty map, which is just
what we want.)


Ages.Update_Element(position => Ages.Find("family name"),
process => Set_Age'access); -- in situ

But note that Ages.Find duplicates the work of Ages.Insert (since Insert must
perform an internal search). If you use an Insert that returns a cursor, then
you can just reuse the cursor, instead of Find'ing it again. Your method works
but it's less efficient.


end loop;
end book2;
.



Relevant Pages

  • Re: Ada.Containers.Indefinite_Ordered_Maps of gcc 4.0.1 has bug ?
    ... Empty_Map: constant Map; ... No_Element: constant Cursor; ... function Length (Container: Map) return Count_Type; ... pragma Inline; ...
    (comp.lang.ada)
  • Re: Run-time accessibility checks
    ... No I made it having same interface, ... container, *because* it is of a different type. ... The cursor is the index in the model you have here. ... to be used to achieve the goal, and secondly return by reference is marked ...
    (comp.lang.ada)
  • Re: Hierarchy Problems
    ... a cursor but it is fast enough. ... SELECT ident, parent, @lvl ... -- get all container rows into a temporary table ... >> You probably get a table scan when you look for the ancestors using the ...
    (microsoft.public.sqlserver.programming)
  • Re: Run-time accessibility checks (was: Construction initialization problem)
    ... container, *because* it is of a different type. ... abstraction, I think you have to go to a fully dynamic language (which Ada ... How to prevent update when a cursor is ... As far as a concurrent environment goes, ...
    (comp.lang.ada)
  • Getting rid of cursors to help with performance
    ... the tables called Container contains a hierarchy system. ... But this function will only accept one container ident, ... SELECT CONTAINERID INTO #tree FROM PQTSELECTION WHERE SESSIONID=@sessionid ... declare objects cursor ...
    (microsoft.public.sqlserver.programming)