Working With Maps Using FLOWR Expressions?
Saturday, 18 April 2015 · 4 messages · last reply 19 Apr 2015
AB
let $map:=map{"a":"old","x":43}
let $seq:=("a","b")
return map:merge(($map,
for $item in $seq return map:entry($item,"somevalue")
))Quoted text · Eliot Kimber · 33 lines
On 18 April 2015 at 17:20, Eliot Kimber <ekimber at 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 > > > >
EK
Eliot Kimber18 Apr 2015 20:20 #
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
EK
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
Quoted text · Andy Bunce · 55 lines
On 4/18/15, 11:43 AM, "Andy Bunce" <bunce.andy at 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 at 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 > > > > > > > >
LW
Leonard Wörteler19 Apr 2015 19:07 #
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
Quoted text · Eliot Kimber · 74 lines
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 at 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 at 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 >> >> >> >> >> >> >> >> > >
Written for BaseX 8.1. BaseX may have changed since: please check the current documentation.
⚡Generated with XQuery