Re: map:group-by or map:build with a sequence of keys?

It's probably best to put comments against the relevant Git issue. We're trying - with limited success - to keep discussions on different topics separate.

Yes, I did see it, and I see pro's and con's in the idea so I'm sitting on the fence.

(a) Dimitre is pushing for maps to be generalised so a key is a sequence of atomic values (or beyond...), and that's a different semantics for allowing map:build to compute multiple keys each of which is atomic.

(b) The current draft of map:build envisages a call to $key() to compute the key, and a call to $value() to compute the corresponding value. If there were multiple keys, would they all map to the same value? Or would you want to generate multiple key-value pairs from a single item in the input sequence? Which would suggest a single callback producing a composite result; but that starts to feel more like the existing map:merge.

I'm all for generalizing functionality but there seems to be a problem generalizing in 3 directions at once.

Michael Kay
Saxonica

> On 17 Oct 2022, at 16:21, Martin Honnen <martin.honnen@gmx.de> wrote:
> 
> Has nobody seen this?
> 
> Or is the group too busy with the weekly agenda and the official PR way
> of suggesting/debating things to be able to respond to suggestions on
> the mailing list?
> 
> Am 10/13/2022 um 2:15 PM schrieb Martin Honnen:
>> 
>> When map:group-by was introduced I found the restriction of a single key
>> instead of a sequence of keys unnecessarily restrictive (some people on
>> Slack agreed), the same appears in my view to be the case for the new
>> map:build, I think it could be easily adapted to handle a sequence of
>> keys by using e.g.
>> 
>>  fold-left($input, map{}, ->($map, $next) {
>> 
>>   fold-left($key($next), $map, ->($map, $key) {
>>    let $nextValue := $value($next) return
>>    if (map:contains($map, $key))
>>    then map:put($map, $key, $combine($map($key), $nextValue))
>>    else map:put($map, $key, $nextValue)})
>>  }
>> )
>> 
>> as the implementation body/definition of the result of
>> 
>> map:build(
>> $input    as item()*,
>> $key    as function(item()) as xs:anyAtomicType*    := fn:identity#1,
>> $value    as function(item()) as item()*    := fn:identity#1,
>> $combine    as function(item()*, item()*) as item()*    := fn:op(',')
>> ) as map(*)
>> 
>> 
>> Use case in my view is the classical example of the XSLT 3 spec where in
>> e.g.
>> 
>> <titles>
>>     <title>A Beginner's Guide to <ix>Java</ix></title>
>>     <title>Learning <ix>XML</ix></title>
>>     <title>Using <ix>XML</ix> with <ix>Java</ix></title>
>> </titles>
>> 
>> you want to group the "title" elements by the "ix" child elements, with
>> the proposed change above that would give e.g.
>> 
>> map {
>>   "Java": (<title>A Beginner's Guide to <ix>Java</ix>
>> </title>, <title>Using <ix>XML</ix> with <ix>Java</ix>
>> </title>),
>>   "XML": (<title>Learning <ix>XML</ix>
>> </title>, <title>Using <ix>XML</ix> with <ix>Java</ix>
>> </title>)
>> }
>> 
>> 
>> XSLT 2/3 grouping always had this feature to allow an item in the
>> grouping population to belong to several groups, the above change would
>> give that same power to XPath/XQuery based grouping using map:build.
>> 
>> 
>> 
>> 
>> 
>> 
>> 
> 

Received on Monday, 17 October 2022 16:11:33 UTC