maps
Friday, 13 July 2018 · 6 messages
GC
Giuseppe Celano13 Jul 2018 00:57 #
Hi
Is it possible to preserve the order of the keys in a map when the map is returned?:
map{"b": 2, "c": 2, "a": 3}
return
map {
"a": 3,
"b": 2,
"c": 2
}Thanks!
Giuseppe
CG
Christian Grün13 Jul 2018 01:01 #
Hi Giuseppe,
XQuery maps are unordered by definition in the specification. If you want to preserve order, you may need to use XML structures, sequences, arrays or additional data structures.
Ciao
Christian
Giuseppe Celano <celano at informatik.uni-leipzig.de> schrieb am Fr., 13. Juli 2018 00:57:
Quoted text · Giuseppe Celano · 19 lines
> Hi > > Is it possible to preserve the order of the keys in a map when the map is > returned?: > > map{"b": 2, "c": 2, "a": 3} > > return > > map { > "a": 3, > "b": 2, > "c": 2 > } > > Thanks! > Giuseppe > >
GC
Hi Christian,
Thanks. I know the order is not significant in maps/json by definition, but I was wondering why to change the original order anyway. I was also trying to hack it adding initial numbers in the key names, but it does not work (but it does if key names are only numbers). What is the BaseX rationale for order?
Bottom line: I am trying to "closely" reproduce some Python code involving dictionaries, where original order in dictionary.keys() is now interestingly kept (from Python 3.6, as far as I know). Unfortunately, the computation on the dictionary values assumes a specific order of the keys (which is not even an alphabetical one )...
Universität Leipzig
Institute of Computer Science, NLP
Augustusplatz 10
04109 Leipzig
Deutschland
E-mail: celano at informatik.uni-leipzig.de
E-mail: giuseppegacelano at gmail.com
Web site 1: http://www.dh.uni-leipzig.de/wo/team/
Web site 2: https://sites.google.com/site/giuseppegacelano/
Quoted text · Giuseppe Celano · 19 lines
> On Jul 13, 2018, at 12:57 AM, Giuseppe Celano <celano at informatik.uni-leipzig.de> wrote: > > Hi > > Is it possible to preserve the order of the keys in a map when the map is returned?: > > map{"b": 2, "c": 2, "a": 3} > > return > > map { > "a": 3, > "b": 2, > "c": 2 > } > > Thanks! > Giuseppe >
CG
Christian Grün13 Jul 2018 11:16 #
Hi Giuseppe,
Quoted text · Giuseppe Celano · 1 line
> I was wondering why to change the original order anyway.
As maps are defined to be unordered in the spec, it is perfectly legal for XQuery processors to change the order of map entries when optimizing the query and constructing the map, and there is no guarantee that the “original order”, which may be derived from the string representation of the query, will be preserved in the compiled query. For example, in the following query, …
map:merge((1 to 100000) ! map:entry(., .))…an implementation may decide to add the 10 input maps in parallel, or to reorder them before adding them to the final map.
Quoted text · Giuseppe Celano · 1 line
> What is the BaseX rationale for order?
BaseX uses a hash-based map implementation, which has no notion of ordering [1]. While the entries of these data structure would yield have a deterministic order when being serialized, this order will have no similarities with the order in which the map entries were written down in the textual query.
Quoted text · Giuseppe Celano · 1 line
> I was also trying to hack it adding initial numbers in the key names, but it does not work (but it does if key names are only numbers).
It might look like that ;) The chosen order (for parts of the data structure) depends on the computed hash code [2].
Quoted text · Giuseppe Celano · 1 line
> Bottom line: I am trying to "closely" reproduce some Python code involving dictionaries, where original order in dictionary.keys() is now interestingly kept (from Python 3.6, as far as I know). Unfortunately, the computation on the dictionary values assumes a specific order of the keys (which is not even an alphabetical one )...
Which ordering criteria does this particular dictionary use?
If performance is not critical (i.e., if you do not plan to store millions of items in the map), you could write a simple XQuery wrapper module that does what you need. If performance is an important factor, and if you have some (more) spare time, you could dive into the fascinating world of Leo’s XQuery data structures [3] and adapt the provided map implementations to your needs…
Christian
[1] https://en.wikipedia.org/wiki/Hash_array_mapped_trie
[2] https://github.com/BaseXdb/basex/blob/master/basex-core/src/main/java/org/basex/query/value/item/ANum.java#L115 [3] https://github.com/LeoWoerteler/xq-modules
GC
Giuseppe Celano13 Jul 2018 11:42 #
Quoted text · Christian Grün · 1 line
> Which ordering criteria does this particular dictionary use?
It is the insertion order. I am just converting this code for pure fun and make some tests. I will definitively have a look at Leo's code as well!
Quoted text · Christian Grün · 48 lines
> On Jul 13, 2018, at 11:16 AM, Christian Grün <christian.gruen at gmail.com> wrote: > > Hi Giuseppe, > >> I was wondering why to change the original order anyway. > > As maps are defined to be unordered in the spec, it is perfectly legal > for XQuery processors to change the order of map entries when > optimizing the query and constructing the map, and there is no > guarantee that the “original order”, which may be derived from the > string representation of the query, will be preserved in the compiled > query. For example, in the following query, … > > map:merge((1 to 100000) ! map:entry(., .)) > > …an implementation may decide to add the 10 input maps in parallel, or > to reorder them before adding them to the final map. > >> What is the BaseX rationale for order? > > BaseX uses a hash-based map implementation, which has no notion of > ordering [1]. While the entries of these data structure would yield > have a deterministic order when being serialized, this order will have > no similarities with the order in which the map entries were written > down in the textual query. > >> I was also trying to hack it adding initial numbers in the key names, but it does not work (but it does if key names are only numbers). > > It might look like that ;) The chosen order (for parts of the data > structure) depends on the computed hash code [2]. > >> Bottom line: I am trying to "closely" reproduce some Python code involving dictionaries, where original order in dictionary.keys() is now interestingly kept (from Python 3.6, as far as I know). Unfortunately, the computation on the dictionary values assumes a specific order of the keys (which is not even an alphabetical one )... > > Which ordering criteria does this particular dictionary use? > > If performance is not critical (i.e., if you do not plan to store > millions of items in the map), you could write a simple XQuery wrapper > module that does what you need. If performance is an important factor, > and if you have some (more) spare time, you could dive into the > fascinating world of Leo’s XQuery data structures [3] and adapt the > provided map implementations to your needs… > > Christian > > [1] https://en.wikipedia.org/wiki/Hash_array_mapped_trie > [2] https://github.com/BaseXdb/basex/blob/master/basex-core/src/main/java/org/basex/query/value/item/ANum.java#L115 > [3] https://github.com/LeoWoerteler/xq-modules >
CG
Christian Grün13 Jul 2018 12:09 #
Quoted text · Giuseppe Celano · 1 line
> It is the insertion order. I am just converting this code for pure fun and make some tests. I will definitively have a look at Leo's code as well!
Feel free to have a look at the attached examples. This “dictionary implementation” (it’s somewhat pretentious to call it like that) uses a simple sequence of XQuery maps with single entries. It’s faster than I had initially expected, but for sure it cannot beat the native map implementation.
Written for BaseX 9.0. BaseX may have changed since: please check the current documentation.
⚡Generated with XQuery