Sequence comparison

Wednesday, 25 November 2020 · 9 messages · last reply 27 Nov 2020
GC
Giuseppe G. A. Celano25 Nov 2020 06:37 #
Hi, I have to compare two sequences and find common items, irrespective of their positions:
for $a  in (1,2,3,5,3)
for $u  in (1,3,2,3)
where $a = $u
group by $o := $a
return
<c>{$a}</c>

This returns
<c>1</c>
<c>2</c>
<c>3 3 3 3</c>
I would like 3 to be repeated only twice (i.e., each item in the first sequence should pair only with one in the second sentence): is there an XQuery "trick" for that in the FLOWR expression?
MH
Martin Honnen25 Nov 2020 08:39 #
Quoted text · Giuseppe G. A. Celano · 19 lines
Am 25.11.2020 um 06:37 schrieb Giuseppe G. A. Celano: > I have to compare two sequences and find common items, irrespective of > their positions: > > for $a in (1,2,3,5,3) > for $u in (1,3,2,3) > where $a = $u > group by $o := $a > return > <c>{$a}</c> > > This returns > <c>1</c> > <c>2</c> > <c>3 3 3 3</c> > > I would like 3 to be repeated only twice (i.e., each item in the first > sequence should pair only with one in the second sentence): is there an > XQuery "trick" for that in the FLOWR expression?
I think
for $a  in (1,2,3,5,3)[. = (1,3,2,3)]
group by $o := $a
return
<c>{$a}</c>
would do that
MH
Martin Honnen25 Nov 2020 09:11 #
Quoted text · Martin Honnen · 30 lines
Am 25.11.2020 um 08:39 schrieb Martin Honnen: > Am 25.11.2020 um 06:37 schrieb Giuseppe G. A. Celano: > >> I have to compare two sequences and find common items, irrespective of >> their positions: >> >> for $a in (1,2,3,5,3) >> for $u in (1,3,2,3) >> where $a = $u >> group by $o := $a >> return >> <c>{$a}</c> >> >> This returns >> <c>1</c> >> <c>2</c> >> <c>3 3 3 3</c> >> >> I would like 3 to be repeated only twice (i.e., each item in the first >> sequence should pair only with one in the second sentence): is there an >> XQuery "trick" for that in the FLOWR expression? > > I think > > for $a in (1,2,3,5,3)[. = (1,3,2,3)] > group by $o := $a > return > <c>{$a}</c> > > would do that
Or more FLOWR like
   for $a  in (1,2,3,5,3)
   where $a . = (1,3,2,3)
   group by $o := $a
   return
   <c>{$a}</c>
GC
Giuseppe G. A. Celano26 Nov 2020 02:28 #
Unfortunately this does not work because, if the second sequence has only one 3 (and the first has two 3), I will still get two 3, while I should get only one.
Quoted text · Martin Honnen · 47 lines
> > Or more FLOWR like > for $a in (1,2,3,5,3) > where $a . = (1,3,2) > group by $o := $a > return > <c>{$a}</c> > On 25. Nov 2020, at 09:11, Martin Honnen <martin.honnen at gmx.de> wrote: > > Am 25.11.2020 um 08:39 schrieb Martin Honnen: >> Am 25.11.2020 um 06:37 schrieb Giuseppe G. A. Celano: >> >>> I have to compare two sequences and find common items, irrespective of >>> their positions: >>> >>> for $a in (1,2,3,5,3) >>> for $u in (1,3,2,3) >>> where $a = $u >>> group by $o := $a >>> return >>> <c>{$a}</c> >>> >>> This returns >>> <c>1</c> >>> <c>2</c> >>> <c>3 3 3 3</c> >>> >>> I would like 3 to be repeated only twice (i.e., each item in the first >>> sequence should pair only with one in the second sentence): is there an >>> XQuery "trick" for that in the FLOWR expression? >> >> I think >> >> for $a in (1,2,3,5,3)[. = (1,3,2,3)] >> group by $o := $a >> return >> <c>{$a}</c> >> >> would do that > > Or more FLOWR like > for $a in (1,2,3,5,3) > where $a . = (1,3,2,3) > group by $o := $a > return > <c>{$a}</c> >
KK
Kristian Kankainen26 Nov 2020 06:33 #
Hello Giuseppe, Would this do what you want: let $reference := (1,3,2,3) for $a in (1,2,3,5,3) where $a = $reference return <c>{$a}</c> Depending on how your $reference looks like, e.g. if it has many duplicates, you can compact it by doing let $reference := distinct- values((1,3,2,3))either way the returned sequence will be identical. Best regards,Kristian Kankainen Ühel kenal päeval, N, 26.11.2020 kell 02:28, kirjutas Giuseppe G. A. Celano:
Quoted text · Giuseppe G. A. Celano · 31 lines
> Unfortunately this does not work because, if the second sequence has > only one 3 (and the first has two 3), I will still get two 3, while I > should get only one. > > Or more FLOWR like for $a in (1,2,3,5,3) where $a . = (1,3,2) > > group by $o := $a return <c>{$a}</c> > > > > > > > On 25. Nov 2020, at 09:11, Martin Honnen <martin.honnen at gmx.de> > > wrote: > > Am 25.11.2020 um 08:39 schrieb Martin Honnen: > > > Am 25.11.2020 um 06:37 schrieb Giuseppe G. A. Celano: > > > > I have to compare two sequences and find common items, > > > > irrespective oftheir positions: > > > > for $a in (1,2,3,5,3)for $u in (1,3,2,3)where $a = $ugroup by > > > > $o := $areturn<c>{$a}</c> > > > > This returns<c>1</c><c>2</c><c>3 3 3 3</c> > > > > I would like 3 to be repeated only twice (i.e., each item in > > > > the firstsequence should pair only with one in the second > > > > sentence): is there anXQuery "trick" for that in the FLOWR > > > > expression? > > > > > > I think > > > for $a in (1,2,3,5,3)[. = (1,3,2,3)]group by $o := > > > $areturn<c>{$a}</c> > > > would do that > > > > Or more FLOWR like for $a in (1,2,3,5,3) where $a . = (1,3,2,3) > > group by $o := $a return <c>{$a}</c>
MH
Martin Honnen26 Nov 2020 07:14 #
My bad, use group by $k := $a return <c>{$a}</c>
-- Diese Nachricht wurde von meinem Android Mobiltelefon mit GMX Mail gesendet. Am 26.11.20, 02:28 schrieb "Giuseppe G. A. Celano" <celano at informatik.uni-leipzig.de>:
Quoted text · Kristian Kankainen · 114 lines
> Unfortunately this does not work because, if the second sequence has only one 3 (and the first has two 3), I will still get two 3, while I should get only one. > > > > > > > > Or more FLOWR like > > > for $a in (1,2,3,5,3) > > > where $a . = (1,3,2) > > > group by $o := $a > > > return > > > <c>{$a}</c> > > > > > > > > > > > > > > > On 25. Nov 2020, at 09:11, Martin Honnen <martin.honnen at gmx.de> wrote: > > > > > > Am 25.11.2020 um 08:39 schrieb Martin Honnen: > > >> Am 25.11.2020 um 06:37 schrieb Giuseppe G. A. Celano: > > >> > > >>> I have to compare two sequences and find common items, irrespective of > > >>> their positions: > > >>> > > >>> for $a in (1,2,3,5,3) > > >>> for $u in (1,3,2,3) > > >>> where $a = $u > > >>> group by $o := $a > > >>> return > > >>> <c>{$a}</c> > > >>> > > >>> This returns > > >>> <c>1</c> > > >>> <c>2</c> > > >>> <c>3 3 3 3</c> > > >>> > > >>> I would like 3 to be repeated only twice (i.e., each item in the first > > >>> sequence should pair only with one in the second sentence): is there an > > >>> XQuery "trick" for that in the FLOWR expression? > > >> > > >> I think > > >> > > >> for $a in (1,2,3,5,3)[. = (1,3,2,3)] > > >> group by $o := $a > > >> return > > >> <c>{$a}</c> > > >> > > >> would do that > > > > > > Or more FLOWR like > > > for $a in (1,2,3,5,3) > > > where $a . = (1,3,2,3) > > > group by $o := $a > > > return > > > <c>{$a}</c> > > > > > > > >
MH
Martin Honnen26 Nov 2020 08:30 #
Quoted text · Martin Honnen · 3 lines
Am 26.11.2020 um 07:14 schrieb Martin Honnen: > My bad, use > group by $k := $a return <c>{$a}</c>
To describe it clearer, the whole FLOWR should be
for $a in (1,2,3,5)
where $a = (1,3,2,3)
group by $k := $a
return
<c>{$a}</c>
GC
Giuseppe G. A. Celano27 Nov 2020 04:38 #
Hi Martin, What I was looking for is a “quick way” to get a comparison such that an item (when it is repeated more than once) is returned only as many times as it appears in both sequences. For example, in
for $a in (1,2,3,5,3,3)
where $a = (1,3,2,3, 2)
group by $k := $a
return
<c>{$a}</c>
you get
<c>1</c>
<c>2</c>
<c>3 3 3</c>
with three 3 even if in the second sequence you have two 3.
Quoted text · Martin Honnen · 14 lines
> On 26. Nov 2020, at 08:30, Martin Honnen <martin.honnen at gmx.de> wrote: > > Am 26.11.2020 um 07:14 schrieb Martin Honnen: >> My bad, use >> group by $k := $a return <c>{$a}</c> > > To describe it clearer, the whole FLOWR should be > > for $a in (1,2,3,5) > where $a = (1,3,2,3) > group by $k := $a > return > <c>{$a}</c> >
G
Graydon27 Nov 2020 07:27 #
Quoted text · Giuseppe G. A. Celano · 5 lines
On Fri, Nov 27, 2020 at 04:38:42AM +0100, Giuseppe G. A. Celano scripsit: > What I was looking for is a “quick way” to get a comparison such that > an item (when it is repeated more than once) is returned only as many > times as it appears in both sequences.
I don't know if it's quick, and I don't know if I understand the requirements, but resorting to maps seems to work:
let $occursMap as function(*) := function($in as xs:integer+) {
  map:merge(
  for $item in $in
    let $key as xs:integer := $item
    group by $key
    (: where $item[2] :)
    return map:entry($key,$item => count())
  )
}

let $a as xs:integer+ := (1,2,3,5,3,3)
let $k as xs:integer+ := (1,3,2,3,2)

let $aMap as map(xs:integer,xs:integer) := $occursMap($a)
let $aKeys as xs:integer+ := $aMap => map:keys()

let $kMap as map(xs:integer,xs:integer) := $occursMap($k)
let $kKeys as xs:integer+ := $kMap => map:keys()

return
  for $each in $aKeys[. = $kKeys]
    return (1 to min(($aMap($each),$kMap($each)))) ! $each
If you need to restrict this to "and they have to occur multiple times in the sequence" as well as "occurs in both sequences", uncomment "where $item[2]".
-- Graydon Saunders | graydonish at gmail.com Þæs oferéode, ðisses swá mæg. -- Deor ("That passed, so may this.")

⚡Generated with XQuery