2016-05-03 12 views
4

Dies ist mehr eine XQuery als MarkLogic. Ich habe drei Karten: Karte und jede Karte hat Schlüssel-Wert-Paar von "ID" und Punktzahl. Ich würde gerne alle eindeutigen IDs basierend auf der Punktzahl von jeder Karte sortieren. Für zB:Sortierung mehrerer Karten in marklogic 8

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

In dem obigen Beispiel ist jede Karte ist ID: Punktzahl für Schlüsselwert (wusste nicht, wie hier :) darzustellen) ..

ich die sortierte Liste von id wollen aus drei Karten basierend auf der Punktzahl ..

Gibt es eine gute oder bessere Möglichkeit, die Sortierung zu tun, oder muss ich die Schlüssel der Karte Union und iterieren Sie die Reihenfolge der Schlüssel und sortieren sie?

+0

Suchen Sie eine kombinierte Punktzahl über Karten? Wenn ja, welche Punktzahl verwenden Sie, wenn dieselbe Taste mehrmals erscheint (wie bei den Tasten 1, 2)? –

+0

Wenn die Schlüssel Konflikt über die Karten .. Ich möchte die höchste Punktzahl auswählen ... In dem obigen Beispiel die 1 von map1 wird für die Sortierung verwendet – Ravi

+2

Bitte post die erwartete Ausgabe mit diesen Beispielkartendaten – har07

Antwort

3

Dies scheint ein großer Anwendungsfall für das Falten. Sein Teil von Xquery 3.0 spec.

Folding kann durch eine Sequenz von Elementen durchlaufen und erhält das Ergebnis für jedes Element, wie es durchläuft. In diesem Beispiel ist $ combinedMaps das Ergebnis des letzten Aufrufs und $ mapToMerge ist das Element in der Sequenz, die es gerade durchläuft.

Hier ein Beispiel, was Sie tun möchten.

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

Ich habe etwas ähnliches auch getan Ich vereinige alle Karten und mache die Reihenfolge nach für die Karte. Aber es ist die gleiche Idee – Ravi