Thread overview
Multidimensional AA question
Nov 26, 2015
André
Nov 27, 2015
Nicholas Wilson
Nov 27, 2015
Jack Applegame
Nov 28, 2015
André
Nov 27, 2015
Jack Applegame
Nov 28, 2015
André
November 26, 2015
Hi,

I have a maybe trivial question on how to insert or update a given entry in a multidimensional AA. So I have this AA:

   /// language, chapter, section. Content is a magic struct
   Content[int][string][string] contentAA;

In some part of my code I want to either add a complete new entry or update an existing one. I just came up with this solution but it seems complex to me:

   string language, chapter;
   int section;
   Content* content;
   if (auto l = language in contentAA) {
       if (auto c = chapter in *l) {
              content = section in *c;
       }
   }
   if (!content) {
       contentAA[language][chapter][section] = Content();
       content = &contentAA[language][chapter][section];
   }
   /// work with content regardless whether it is updated or newly inserted

My question now is: is there some more elegant solution to achieve this? Something like in C++ when you have std::map's of std::map's and just access the elements and the entry is created implicitly? Basically I would want to just have this line working out of the box:

   content = &contentAA[language][chapter][section];

.. and the AA would make sure the element is created if it didn't exist before. I know I could create a function for that but I am looking for a standard approach that already exists.

Thanks!
André

November 27, 2015
On Thursday, 26 November 2015 at 17:27:34 UTC, André wrote:
> Hi,
>
> I have a maybe trivial question on how to insert or update a given entry in a multidimensional AA. So I have this AA:
>
>    /// language, chapter, section. Content is a magic struct
>    Content[int][string][string] contentAA;
>
> In some part of my code I want to either add a complete new entry or update an existing one. I just came up with this solution but it seems complex to me:
>
>    string language, chapter;
>    int section;
>    Content* content;
>    if (auto l = language in contentAA) {
>        if (auto c = chapter in *l) {
>               content = section in *c;
>        }
>    }
>    if (!content) {
>        contentAA[language][chapter][section] = Content();
>        content = &contentAA[language][chapter][section];
>    }
>    /// work with content regardless whether it is updated or newly inserted
>
> My question now is: is there some more elegant solution to achieve this? Something like in C++ when you have std::map's of std::map's and just access the elements and the entry is created implicitly? Basically I would want to just have this line working out of the box:
>
>    content = &contentAA[language][chapter][section];
>
> .. and the AA would make sure the element is created if it didn't exist before. I know I could create a function for that but I am looking for a standard approach that already exists.
>
> Thanks!
> André

AA are weird in that AFAIK you need to "initialise" them before you try to look suff up in them else they crash. i.e.
int[string] foo;
// auto e = "1" in foo; // crash AA not initialised
foo[ "blah"] = 0;
foo.remove("blah");
auto e = "1" in foo; //doesn't crash

have you tried using aa.get(key,default);?
i.e. contentAA.get(language,"english").get(section, "somedefault").get(section,0);


other than that are you likey to have missing sections? (i.e. do you need an AA for section or can you just use an array?)
similarly; does chapter need to be indexed by string? can you get away with indexing by chapter number and storing an array of chapter names and looking that up when needed?

Nic
November 27, 2015
On Friday, 27 November 2015 at 04:21:41 UTC, Nicholas Wilson wrote:
> AA are weird in that AFAIK you need to "initialise" them before you try to look suff up in them else they crash. i.e.
> int[string] foo;
> // auto e = "1" in foo; // crash AA not initialised
> foo[ "blah"] = 0;
> foo.remove("blah");
> auto e = "1" in foo; //doesn't crash

It's not true.
"Not initalzed" AA s just empty AA.
http://dpaste.dzfl.pl/82b38a2ad504
November 27, 2015
On Thursday, 26 November 2015 at 17:27:34 UTC, André wrote:
> My question now is: is there some more elegant solution to achieve this? Something like in C++ when you have std::map's of std::map's and just access the elements and the entry is created implicitly?
No. But you can create a wrapper:
http://dpaste.dzfl.pl/80ad84e8f010
November 28, 2015
On Friday, 27 November 2015 at 08:53:18 UTC, Jack Applegame wrote:
> On Thursday, 26 November 2015 at 17:27:34 UTC, André wrote:
>> My question now is: is there some more elegant solution to achieve this? Something like in C++ when you have std::map's of std::map's and just access the elements and the entry is created implicitly?
> No. But you can create a wrapper:
> http://dpaste.dzfl.pl/80ad84e8f010

Thank you very much! That's a nice piece of code. I was looking for something like that in the standard library - to me it seems like something others might need regularly too.

Regards,
André
November 28, 2015
On Friday, 27 November 2015 at 04:21:41 UTC, Nicholas Wilson wrote:
> AA are weird in that AFAIK you need to "initialise" them before you try to look suff up in them else they crash. i.e.
> int[string] foo;
> // auto e = "1" in foo; // crash AA not initialised
> foo[ "blah"] = 0;
> foo.remove("blah");
> auto e = "1" in foo; //doesn't crash
>
> have you tried using aa.get(key,default);?
> i.e. contentAA.get(language,"english").get(section, "somedefault").get(section,0);

That doesn't work for my use case unfortunately. The object I am getting of this call isn't the one I would like update at [language][chapter][section]. I really need a pointer or reference to the object that is held my the map.


> other than that are you likey to have missing sections? (i.e. do you need an AA for section or can you just use an array?)
> similarly; does chapter need to be indexed by string? can you get away with indexing by chapter number and storing an array of chapter names and looking that up when needed?

Chapter is indeed the chapter's title. But you are right - the sections could be an usual array. Still the problem still is the same for the first two dimensions.