Thread overview
ordered Associative array
Apr 14, 2017
Jethro
Apr 14, 2017
solidstate1991
Apr 14, 2017
H. S. Teoh
April 14, 2017
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.

April 14, 2017
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/PixelPerfectEngine/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.
April 13, 2017
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