Dynamics AX
  RSS Feed  LinkedIn  Twitter
Want to turn you're data into a true asset? Ready to break free from the report factory?
Ready to gain true insights that are action focused for truly data informed decisions?
Want to do all of this across mutliple companies, instances of Dynamics and your other investments?
Hillstar Business Intelligence is the answer then! (www.HillstarBI.com)

Hillstar Business Intelligence for Microsoft Dynamics AX and NAV on Mobile, Desktop, Tablet


Let us prove to you how we can take the complexity out of the schema and truly enable users to answer the needed questions to run your business! Visit Hillstar Business Solutions at: www.HillstarBI.com

Tuesday, October 14, 2008

Map Object Sorting - a real issue

Alright,

So I am sure everyone has used Map objects in writing X++ code before. Map's are part of Collection classes that exist inside Dynamics AX.

Well one of the strangest things about this Collection class, is that it's lack or sorting methods. It does not have any. You can't sort a Map object by values or Keys, and if you can, it's buried so deep that no one has wrote about it or found it.

What kind of sorting I did see today, with my partner in crime Derek Pate, was based on the Type for the Key value of the map.

For example, say you have:

3,4,5,6,7,8,10,12,14,16

as values. Now if these values are integer based from the source your pulling from or you convert to, and you take and insert these values as listed with some form of while loopping on the object that carried these values for you, sorted in the above way, you would expect these to appear in the object your inserting too, in that same sorted order. Right?

Wrong!

If you are trying to insert the above values, of type integer, into a Map of Types::String, Types::String you will end up with the following sorted values for that Map's value elements:

"10","12","14","16","3","4","5","6","7","8"

So even though there is not a known / published sorting method or built-in function for sorting a Map, it tries to automatically sort the values for you based on type, even though you inserted those values into the map object the order desired.

This is one of those strange things that exists, that should not actually. The ability to sort, and sorting to exist for the developer at hand. Not a guessed sorting order, based on type.

Maybe an improvement suggestion? Have you seen this before? Do you have a sorting method you like to use for Map Object Values? Let me know here... and check back soon!

Update: I have had some really good comments on this entry, that point out the fact this is actually documented behavior. And based on that documented behavior, and the Key Type for the map, this is working as expected. Still it would be nice to have the ability to do your own sorting, with some kind of method of off the Map Class itself.

Here is the information pointed out:
"The order in which the elements occur during iteration is defined not by the sequence in which the elements are inserted, but the ordering of the elements: Elements with lower keys appear before elements with higher keys. The usual ordering for the types is in effect. However, for if the keys are objects, the addresses of the objects are used to supply the ordering, and no specific ordering may consequently be inferred: The addresses of the objects are transient by nature"

Thanks to the following:
Palle Agermark, Jan B. Kjeldsen & Torben for adding the comments.

Honestly, I have just nevet ran into this before, as the Types:: for the key value was always ok and the odering / sorting was never an issue. Thanks again!




"Visit the Dynamics AX Community Page today!"


Labels: , , , , , , , ,

4 Comments:

Blogger Palle Agermark said...

When reading this article I must say that the Map behaves as I would have expected it to. The function of a Map is that you under some key store a value, and since focus is on retreiving the value again fast by knowing the key, it makes sense to me that the keys are sorted.

To sort the values of the Map, I'd get the Set of values from the Map and then write some sorting algorithm on that

1:07 AM  
Blogger Jan B. Kjeldsen said...

I'm not sure I get it.

MapEnumrator and MapIterator returns the elements sorted on the key value.

This is spelled out clearly in the documentation of MapIterator (but not MapEnumerator):

"The order in which the elements occur during iteration is defined not by the sequence in which the elements are inserted, but the ordering of the elements: Elements with lower keys appear before elements with higher keys. The usual ordering for the types is in effect. However, for if the keys are objects, the addresses of the objects are used to supply the ordering, and no specific ordering may consequently be inferred: The addresses of the objects are transient by nature."

Use a list if you want to retrieve the elements in the order you insert them.

3:14 AM  
Blogger Torben said...

Hi there,

for the record, the sorting order is well defined for all collection classes in the Axapta online documentation, at least for Version 3.0. The only culprit is, that you usually have to look in the Iterator / Enumeratro classes, f.x. from MapIterator:

---
The order in which the elements occur during iteration is defined not by the sequence in which the elements are inserted, but the ordering of the elements: Elements with lower keys appear before elements with higher keys. The usual ordering for the types is in effect. However, for if the keys are objects, the addresses of the objects are used to supply the ordering, and no specific ordering may consequently be inferred: The addresses of the objects are transient by nature.
---

So the usual thing is to construct adequate keys for sorting, which works quite well. Note, that sorting is very dependant on the actual collection class you use. A List for example lets you define the ordering by the way you insert the object, an Array lets you use a custom index (like any primitive type Array does) and a Set uses the Value itself for sorting.


Greetings,
Torben

3:36 AM  
Blogger JACOB-NO said...

In cases where I don't need the lookup, but need sorting while using MapEnumerator, I normally make the key a container and then in the first element of the container i put the "sort key". When I then loop the container it's "sorted" for me ;)

The code becomes slightly more verbose but still it's very useful at some times.
If you also need the lookup it's then possible to have 2 maps, one sorted and another one that keeps tracks of they original key and has the container key is it's value.
Even more verbose..

For anything more complicated than this I fall back to a temp table if the performance hit is acceptable :)

3:47 PM  

Post a Comment

Links to this post:

Create a Link

<< Home


Copyright 2005-2011, J. Brandon George - All rights Reserved