[Bug 29660] New: map:remove and array: remove should support removing multiple entries

https://www.w3.org/Bugs/Public/show_bug.cgi?id=29660

            Bug ID: 29660
           Summary: map:remove and array:remove should support removing
                    multiple entries
           Product: XPath / XQuery / XSLT
           Version: Candidate Recommendation
          Hardware: PC
                OS: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Functions and Operators 3.1
          Assignee: mike@saxonica.com
          Reporter: josh.spiegel@oracle.com
        QA Contact: public-qt-comments@w3.org
  Target Milestone: ---

I think it may improve usability if we modify map:remove to take a sequence of
key values instead of a single key value.  This would make it easier to
conditionally remove entries from a map.

Consider this map:

   declare variable $m := map {
     0 : "blue",
     2 : "red",
     4 : "blue",
     6 : "green"
   };

Assume the goal is to remove the "blue" entries without knowing the keys in
advance.  I came up with two solutions for this.  The first uses a recursive
user defined function:

  declare function local:removeAll($m as map(*), $keys) {
    if (exists($keys)) then
       local:removeAll(map:remove($m,$keys[1]), tail($keys))
    else
       $m
  };

  local:removeAll($m, map:keys($m)[$m(.) eq "blue"])

Here is another solution that filters and reconstructs:

  map:merge(
    for $k in map:keys($m)
    where $m($k) ne "blue"
    return 
      map:entry($k, $m($k))
  )


It is more succinct and I think more intuitive to use map:remove directly:

  map:remove($m, map:keys($m)[$m(.) eq "blue"])

If this change makes sense, then I expect we would want to consider making a
similar change to array:remove as well.

-- 
You are receiving this mail because:
You are the QA Contact for the bug.

Received on Tuesday, 24 May 2016 16:06:14 UTC