www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - ordered Associative array

reply Jethro <qyzz gr.ff> writes:
Is there a way to retain the ordering of an associative array? 
When the elements are added then looped over using a foreach, the 
order is different.
Apr 13 2017
next sibling parent solidstate1991 <laszloszeremi outlook.com> writes:
On Friday, 14 April 2017 at 00:29:34 UTC, Jethro wrote:
 Is there a way to retain the ordering of an associative array? 
 When the elements are added then looped over using a foreach, 
 the order is different.
Use a separate array to store the keys, order them all time when you add a new one, etc. This was the only workaround I could come up with for my engine (see it here: https://github.com/ZILtoid1991/pixelperfectengine/blob/master/source/PixelPerfectEngi e/graphics/layers.d at Classes SpriteLayer and SpriteLayer32Bit), maybe in the future I'll come up with a better solution. I call this technique as "prioritized hash table" as the keys give them a certain priority, so there's no issue which sprite where supposed to show up.
Apr 13 2017
prev sibling parent "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Fri, Apr 14, 2017 at 12:29:34AM +0000, Jethro via Digitalmars-d-learn wrote:
 Is there a way to retain the ordering of an associative array? When
 the elements are added then looped over using a foreach, the order is
 different.
An AA is implemented as an unordered hash. So the insertion order is usually unrelated to the foreach order. If you want keys to be sorted according to some order, consider using std.container.rbtree instead. If you want to retain insertion order, you could wrap an AA inside a custom container that keeps track of insertion order. Something along these lines: /* Warning: untested, proof-of-concept code. This assumes you * never remove stuff from the AA. If you want to support * .remove you'll have to do a bit more work, obviously. */ struct InsertionOrderAA(K,V) { V[K] _impl; K[] keyOrder; void opIndexAssign(V value, K key) { _impl[key] = value; keyOrder ~= key; } Value opIndex(K key) { return _impl[key]; } void opApply(scope void delegate(K,V) dg) { foreach (key; keyOrder) { auto ret = dg(key, _impl[key]); if (ret != 0) return ret; } } } T -- I am not young enough to know everything. -- Oscar Wilde
Apr 13 2017