2016-05-03 14 views
4

これはMarkLogic以外のXQueryによく似ています。私は3つのマップを持っています:マップと各マップは、 "ID"とスコアのキーと値のペアを持っています。私は各マップからのスコアに基づいてすべての別個のIDをソートしたいと思います。例えばのために :marklogicで複数のマップを並べ替える8

map1 : 1:2048, 5:2000 
map2 : 2:5000, 1:1000, 4:3000 
map3 : 6:100, 7:5000, 2:2000 

上記の例では、各マップは、ID:キー値のスコア(:)ここで表す方法を知りませんでした)。..

私はIDのソートされたリストから欲しいですスコアに基づいた3つのマップ..

ソートを行うには良い方法がありますか、またはマップのキーを結合してキーのシーケンスを繰り返しソートする必要がありますか?

+0

地図全体で1つの総合スコアをお探しですか?もしそうなら、同じキーが複数回現れたときにどのスコアを使用しますか? –

+0

キーがマップ全体で競合する場合...最高のスコアを選択したい...上記の例では、map1からの1がソートに使用されます – Ravi

+2

これらのサンプルマップデータを指定して期待される出力を投稿してください – har07

答えて

3

これはフォールディングの大きなユースケースのようです。 Xquery 3.0仕様の一部です。

Foldingは、一連のアイテムを通過し、各アイテムの結果を取得します。この例では$ combinedMapsは最後の呼び出しの結果であり、$ mapToMergeは現在通過しているシーケンス内の項目です。

ここでは、何をしたいかの例を示します。

declare function local:sortMaps(
    $newMap as map:map, 
    $mapA as map:map, 
    $mapB as map:map 
) as map:map { 
    let $build := 
    for $key in map:keys($mapA) 
    let $otherMapValue := 
     (map:get($mapB, $key), 0)[1] 
    let $value := map:get($mapA, $key) 
    return 
     if ($value gt $otherMapValue) then (
     map:put($newMap, $key, $value) 
    ) else (
     map:put($newMap, $key, $otherMapValue) 
    ) 
    return $newMap 
}; 

let $map1 := 
    map:new((
    map:entry("1",2048), 
    map:entry("5",2000) 
)) 

let $map2 := 
    map:new((
    map:entry("2",5000), 
    map:entry("1",1000), 
    map:entry("4",3000) 
)) 

let $map3 := 
    map:new((
    map:entry("6",100), 
    map:entry("7",5000), 
    map:entry("2",2000) 
)) 

let $maps := ($map1, $map2, $map3) 
return 
    fn:fold-left(
    function($combinedMaps, $mapToMerge) { 
     let $newMap := map:map() 
     let $newMap := local:sortMaps($newMap, $combinedMaps, $mapToMerge) 
     let $newMap := local:sortMaps($newMap, $mapToMerge, $combinedMaps) 
     return $newMap 
    }, 
    $maps[1], 
    $maps 
) 
+0

私も同様のことをしました、私は全ての地図を結合し、地図のために注文する。しかしそれは同じ考えである – Ravi

関連する問題