我有以下地图:
let $input := map { 'a-key': 'a-value', 'b-key': ['b-value-1', 'b-value-2'] }
(b-key
数组的长度可以变化,也可以不存在; a-key
可以存在或不存在)
我需要创建以下数组:
[ ('a', 'b', 'b'), 'a-value', 'b-value-1', 'b-value-2' ]
第一个序列中b
的数量应与b-value
s的数量相对应。
我几乎尝试了iterating / map:for-each的每种组合,等等,该数组最终以太多的嵌套或完全平坦的方式结束了。
(n.b。数组将使用fn:apply
传递给函数-而不是我的!因此必须采用这种形式)
答案 0 :(得分:2)
构建包含动态构建的序列的数组似乎很困难,我认为您首先需要将序列构建为变量,然后使用方括号数组构造函数[$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?* }))
答案 1 :(得分:1)
If you are comfortable with the functional-programming side of XQuery, you can create the whole output in two nested "loops" (i.e. fold
s), one over the keys and the other one over those values that are arrays:
(: 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)
})
You can even abbreviate the array(*)
case as return array:fold-left($val, $arr, $update-arr(?, $k, ?))
if you want.
The result is [("a", "b", "b"), "a-value", "b-value-1", "b-value-2"]
as expected.