Working With Maps Using FLOWR Expressions?
I think I'm missing something fundamental but I haven't been able to find a relevant example of what I'm trying to do. I suspect I'm being derailed by procedural brain damage. I have a function that takes as input a map and will return a new map reflecting updates applied to input map. The business logic of this function is to iterate over some sequence and add or update map items as needed, e.g.: let $map := map { } for $key in ('A', 'B') return map:put($map, 'A', 'somevalue') The problem is that each interation of the for loop returns a new map. In the context of a FLOWR expression I'm not seeing how to effectively update the same map instance. What fundamental aspect of map manipulation am I missing? Thanks, Eliot ————— Eliot Kimber, Owner Contrext, LLC http://contrext.com
Hi Eliot, Take a look at map:entry and map:merge[1] let $map:=map{"a":"old","x":43} let $seq:=("a","b") return map:merge(($map, for $item in $seq return map:entry($item,"somevalue") )) /Andy [1] http://docs.basex.org/wiki/Map_Module#map:entry On 18 April 2015 at 17:20, Eliot Kimber <ekimber@contrext.com> wrote:
I think I'm missing something fundamental but I haven't been able to find a relevant example of what I'm trying to do. I suspect I'm being derailed by procedural brain damage.
I have a function that takes as input a map and will return a new map reflecting updates applied to input map.
The business logic of this function is to iterate over some sequence and add or update map items as needed, e.g.:
let $map := map { } for $key in ('A', 'B') return map:put($map, 'A', 'somevalue')
The problem is that each interation of the for loop returns a new map.
In the context of a FLOWR expression I'm not seeing how to effectively update the same map instance.
What fundamental aspect of map manipulation am I missing?
Thanks,
Eliot ————— Eliot Kimber, Owner Contrext, LLC http://contrext.com
Of course. Must be my lack of sleep that kept me from seeing that solution :-) Cheers, E. ————— Eliot Kimber, Owner Contrext, LLC http://contrext.com On 4/18/15, 11:43 AM, "Andy Bunce" <bunce.andy@gmail.com> wrote:
Hi Eliot,
Take a look at map:entry and map:merge[1]
let $map:=map{"a":"old","x":43}
let $seq:=("a","b") return map:merge(($map, for $item in $seq return map:entry($item,"somevalue") ))
/Andy [1] http://docs.basex.org/wiki/Map_Module#map:entry
On 18 April 2015 at 17:20, Eliot Kimber <ekimber@contrext.com> wrote:
I think I'm missing something fundamental but I haven't been able to find a relevant example of what I'm trying to do. I suspect I'm being derailed by procedural brain damage.
I have a function that takes as input a map and will return a new map reflecting updates applied to input map.
The business logic of this function is to iterate over some sequence and add or update map items as needed, e.g.:
let $map := map { } for $key in ('A', 'B') return map:put($map, 'A', 'somevalue')
The problem is that each interation of the for loop returns a new map.
In the context of a FLOWR expression I'm not seeing how to effectively update the same map instance.
What fundamental aspect of map manipulation am I missing?
Thanks,
Eliot ————— Eliot Kimber, Owner Contrext, LLC http://contrext.com
Hi Eliot, while Andy's solution using `map:merge($maps)` works great in your specific case, the general pattern (i.e. updating some local state while iterating over a sequence) is also implemented in the extremely versatile higher-order `fn:fold-left($seq, $start, $func)` function [1] (and its sibling `array:fold-left($array, $start, $func)` [2]). Using that you can implement your logic roughly as follows: let $map := map { } return fold-left( ('A', 'B'), $map, function($curr-map, $item) { map:put($curr-map, $item, 'somevalue') } ) Hope that helps, Leo [1] http://www.w3.org/TR/xpath-functions-31/#func-fold-left [2] http://www.w3.org/TR/xpath-functions-31/#func-array-fold-left Am 18.04.2015 um 18:52 schrieb Eliot Kimber:
Of course.
Must be my lack of sleep that kept me from seeing that solution :-)
Cheers,
E. ————— Eliot Kimber, Owner Contrext, LLC http://contrext.com
On 4/18/15, 11:43 AM, "Andy Bunce" <bunce.andy@gmail.com> wrote:
Hi Eliot,
Take a look at map:entry and map:merge[1]
let $map:=map{"a":"old","x":43}
let $seq:=("a","b") return map:merge(($map, for $item in $seq return map:entry($item,"somevalue") ))
/Andy [1] http://docs.basex.org/wiki/Map_Module#map:entry
On 18 April 2015 at 17:20, Eliot Kimber <ekimber@contrext.com> wrote:
I think I'm missing something fundamental but I haven't been able to find a relevant example of what I'm trying to do. I suspect I'm being derailed by procedural brain damage.
I have a function that takes as input a map and will return a new map reflecting updates applied to input map.
The business logic of this function is to iterate over some sequence and add or update map items as needed, e.g.:
let $map := map { } for $key in ('A', 'B') return map:put($map, 'A', 'somevalue')
The problem is that each interation of the for loop returns a new map.
In the context of a FLOWR expression I'm not seeing how to effectively update the same map instance.
What fundamental aspect of map manipulation am I missing?
Thanks,
Eliot ————— Eliot Kimber, Owner Contrext, LLC http://contrext.com
participants (3)
-
Andy Bunce -
Eliot Kimber -
Leonard Wörteler