XQuery: сопоставление с массивом последовательностей - PullRequest
1 голос
/ 19 марта 2019

У меня есть следующая карта:

let $input := map { 'a-key': 'a-value', 'b-key': ['b-value-1', 'b-value-2'] }

(длина массива b-key может изменяться или отсутствовать; a-key может присутствовать или отсутствовать)

Iнеобходимо создать следующий массив:

[ ('a', 'b', 'b'), 'a-value', 'b-value-1', 'b-value-2' ]

Число b s в первой последовательности должно соответствовать числу b-value s.

Я уже пробовал примернокаждая комбинация итерации / карты: для каждого и т. д., и массив либо заканчивается слишком большим количеством вложений, либо полностью плоским ...

(nb массив должен быть передан функции - немой! - используя fn:apply, поэтому должен быть в этой форме)

Ответы [ 2 ]

2 голосов
/ 19 марта 2019

Кажется трудным построить массив, содержащий последовательность, которая создается динамически, я думаю, что сначала вам нужно построить последовательность в переменную, а затем использовать конструктор массива в квадратных скобках [$seq], чтобы создать массив с последовательностью в качествеодин элементТогда вы можете array:join другие значения:

let $input := map { 'a-key': 'a-value', 'b-key': ['b-value-1', 'b-value-2'] }
let $seq := ($input?a-key!'a', (1 to array:size($input?b-key))!'b')
return 
    array:join(([$seq], array {$input?a-key, $input?b-key?* }))

https://xqueryfiddle.liberty -development.net / nbUY4ku / 2

1 голос
/ 19 марта 2019

Если вас устраивает сторона функционального программирования в XQuery, вы можете создать весь вывод в виде двух вложенных «циклов» (т. Е. fold s ), один поверх клавиш, а другойнад значениями, которые являются массивами:

(: the input :)
let $input := map { 'a-key': 'a-value', 'b-key': ['b-value-1', 'b-value-2'] }

(: utility function that adds a single key/value pair to the output array :)
let $update-arr :=
    function($arr, $k, $v) {
      array:append(array:put($arr, 1, ($arr(1), $k)), $v)
    }

(: nested folds over keys and values :)
return fold-left(map:keys($input), [()], function($arr, $key) {
  let $k := substring-before($key, '-key')
  let $val := $input($key)
  return typeswitch($val)
    case array(*)
      return array:fold-left($val, $arr, function($arr2, $v) {
        $update-arr($arr2, $k, $v)
      })
    default
      return $update-arr($arr, $k, $val)
})

Вы можете даже сокращать регистр array(*) как return array:fold-left($val, $arr, $update-arr(?, $k, ?)), если хотите.

Результат - [("a", "b", "b"), "a-value", "b-value-1", "b-value-2"], как и ожидалось.

...