From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,693e247f5dca709d X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!news4.google.com!news.glorb.com!proxad.net!proxad.net!newsfeed.arcor.de!newsspool3.arcor-online.net!news.arcor.de.POSTED!not-for-mail Newsgroups: comp.lang.ada Subject: Re: How to use associative arrays in Ada 2005? From: Georg Bauhaus In-Reply-To: <1164310051.811802.237400@l12g2000cwl.googlegroups.com> References: <1164103903.240838.37230@j44g2000cwa.googlegroups.com> <1164152113.623461.130190@e3g2000cwe.googlegroups.com> <1164310051.811802.237400@l12g2000cwl.googlegroups.com> Content-Type: text/plain Content-Transfer-Encoding: 7bit Organization: # Message-Id: <1164328429.5590.61.camel@localhost.localdomain> Mime-Version: 1.0 X-Mailer: Evolution 2.6.1 Date: Fri, 24 Nov 2006 01:33:49 +0100 NNTP-Posting-Date: 24 Nov 2006 01:33:45 CET NNTP-Posting-Host: 5a735007.newsspool3.arcor-online.net X-Trace: DXC=J:Gd9?oS?2AX36K@\WTHGJMcF=Q^Z^V3H4Fo<]lROoRAgUcjd<3m<;B5JX?Rh3eMbJPCY\c7>ejVH5WPU;Fgl\dN?HM_V5lA9jB X-Complaints-To: usenet-abuse@arcor.de Xref: g2news2.google.com comp.lang.ada:7671 Date: 2006-11-24T01:33:45+01:00 List-Id: On Thu, 2006-11-23 at 11:27 -0800, snoopysalive wrote: > > The statement "Ages.Insert("family name",Insert("name",23));" doesn't > work. So, how is it possible to do something like this in C++: > "... > map> ages; > ages["family name"]["name"] = 23; > ..." I think that in this case the Ada.Containers requirement of being minimal building blocks applies. And probably also the principle of query/command separation, which is not followed by std::map::operator[]. [] does many things at the same time, hence it is not minimal. If I remember Matt's tutorial correctly, there is an example showing how to manipulate items in containers in situ. Barnes' book has this, too. If the elements in a map are containers themselves (or are otherwise big), you may want to use Update_Element. If you have +-----------+ +--> | ... | +-------------+ | +-----------+ | ... | --+ | ... | +--> ... +-------------+ +----------+ | | family name | --> | ... | ---+ +-------------+ +----------+ | ... | | name | ------> 23 +----------+ | ... | That is in order to manipulate one of the 2nd level maps, you could either: - Get the element at key "family name", which is a map. This creates a copy of the map. - Manipulate the copied map. - Put the map back to where it had been (at key "family name"), again copying. 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. with Ada.Text_IO, Ada.Strings.Hash, Ada.Containers.Indefinite_Hashed_Maps; use Ada.Text_IO, Ada.Strings, Ada.Containers; procedure book2 is package Str_Int_Maps is new Ada.Containers.Indefinite_Hashed_Maps (String, Integer, Ada.Strings.Hash, "="); use Str_Int_Maps; package Str_Map_Maps is new Ada.Containers.Indefinite_Hashed_Maps (String, Str_Int_Maps.Map, Ada.Strings.Hash, "="); Ages : Str_Map_Maps.Map; -- That's the "hash of a hash" Named_Age: Str_Int_Maps.Map; -- life by population statistics: Average: constant Natural := 80; function Grow_Older(Now: Integer) return Integer is separate; -- used to compute a new `Age` from `Now` Age: Integer := 0; 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 end Set_Age; begin Ages.Insert("family name", Named_Age); while Age < Average loop Age := Grow_Older(Age); -- Ages.Update_Element(position => Ages.Find("family name"), process => Set_Age'access); -- in situ end loop; end book2; This might seem like a lot, but once you have your setup, you can reuse it, or write []-style wrappers, if you need them etc.. Scope is important in this example, because the `Age` variable is visible to Set_Age, and need not be passed around.