XQuery/Fizzbuzz
外觀
< XQuery
檢視 [1] 以獲取完整的可執行指令碼集和計時比較。
這是對 David Patterson 在 David Patterson 的部落格中提出的 FizzBuzz 問題 的 XQuery 解決方案。他寫了一個 XSLT 解決方案。
Chris Wallace 為 David 的可配置版本問題編寫了此解決方案
let $config :=
<fizzbuzz>
<range min="1" max="100"/>
<test>
<mod value="3" test="0">Fizz</mod>
<mod value="5" test="0">Buzz</mod>
</test>
</fizzbuzz>
return
string-join(
for $i in ($config/range/@min to $config/range/@max)
let $s :=
for $mod in $config/test/mod
return
if ($i mod $mod/@value = $mod/@test)
then string($mod)
else ()
return
if (exists($s))
then string-join($s,' ')
else string($i),
"
"
)
該演算法的引數化是在 David Patterson 提出的原始問題中。如果引數固定,則可以實現更簡單的解決方案。
以下是由 Jim Fuller 提供的解決方案
for $n in (1 to 100) let $fizz := if ($n mod 3) then () else "fizz" let $buzz := if ($n mod 5) then () else "buzz" return if ($fizz or $buzz) then concat($fizz,$buzz) else $n
以下是由 Dimitre Novatchev 提供的簡短而簡單的解決方案 - 請注意,沒有顯式的 if ... then ... else。 (另外,如果消除 $fizz 和 $buzz 變數,則可以縮短為 3 行)
for $n in (1 to 100),
$fizz in not($n mod 3),
$buzz in not($n mod 5)
return
concat("fizz"[$fizz], "buzz"[$buzz], $n[not($fizz or $buzz)])
可以注意到,以上解決方案沒有使用任何 XPath 中沒有的 XQuery 特性 - 因此這是一個純 XPath 2.0 解決方案。
Dimitre 的另一個解決方案,它可能更快,因為它根本不使用任何 mod 運算子
for $k in 1 to 100 idiv 15 +1,
$start in 15*($k -1) +1,
$end in min((100, $start + 14))
return
let $results :=
($start, $start+1,
'fizz',
$start+3,
'buzz', 'fizz',
$start+6, $start+7,
'fizz',
'buzz',
$start+10,
'fizz',
$start+12, $start+13,
'fizzbuzz')
return
subsequence($results, 1, $end -$start +1)
同樣,以上解決方案沒有使用任何 XPath 3.0 中沒有的 XQuery 特性 - 因此這是一個純 XPath 3.0 解決方案。
以下是由 Dino Fancellu 提供的解決方案,純 XPath 3.0
(1 to 30)!(if (. mod 15=0) then "fizzbuzz" else if (. mod 3 = 0) then "fizz" else if (. mod 5 = 0) then "buzz" else .)
以下是由 Benito van der Zander 提供的解決方案,純 XPath 3.0,無 if
for $i in 1 to 100 return (("fizz"[$i mod 3=0] || "buzz"[$i mod 5=0])[.],$i)[1]