2017-06-27 3 views
1

ich zur Zeit der Suche in jq mit JSON-Dateien zu verarbeiten, die Listen von ganzen Zahlen, wie das folgende Beispiel enthält -Verarbeitung JSON-Dateien Listen von ganzen Zahlen enthalten jq mit

[ 
    { 
    "box_id": 1, 
    "number_items": [ 
     4, 
     6, 
     7, 
     5 
    ] 
    }, 
    { 
    "box_id": 3, 
    "number_items": [ 
     15, 
     null, 
     15, 
     9 
    ] 
    }, 
    { 
    "box_id": 6, 
    "number_items": [ 
     2, 
     4, 
     0, 
     1 
    ] 
    } 
] 

Erstens, ich bin versucht zu Holen Sie das Maximum für jede box_id. Nur die maximalen Werte zu erhalten, ist relativ einfach mit z.B. jq '.[].number_items | max, die

7 
15 
4 

jedoch zurückkehrt, würde Ich mag diese in eine Datei neue JSON speichern, wie so -

[ 
    { 
    "box_id": 1, 
    "max_items": 7 
    }, 
    { 
    "box_id": 3, 
    "max_items": 15 
    }, 
    { 
    "box_id": 6, 
    "max_items": 4 
    } 
] 

Der andere Teil etwas mehr beteiligt ist - wie die Summe der Absolut finden Unterschiede der aufeinander folgenden Einträge in den Listen für jede box_id? Als Beispiel betrachte man [4,6,7,5], was den Unterschieden [6-4=2, 7-6=1, 5-7=-2] = [2,1,-2] entspricht. Die Summe der absoluten Werte von diesem ist 2+1+2 = 5. Beachten Sie, dass die Listen null Werte enthalten können. Diese Einträge sollten entfernt werden, so dass wir im Fall [15,null,15,9][15,15,9] erhalten, was den Unterschieden [0,-6] und der absoluten Summe 6 entspricht.

+0

zeigen das Endergebnis einschließlich * absolute Werte * – RomanPerekhrest

Antwort

2

Mit einem klein wenig Vertrautheit mit jq, ist das erste Problem trivial, so werde ich nicht mehr sagen, als eine Lösung geben:

map({box_id, max_items: (.number_items | max) }) 

Die Anforderungen für das zweite Problem ein wenig unklar, aber Sie können das Folgende ganz einfach an Ihre Bedürfnisse anpassen. Zunächst wird eine Hilfsfunktion, differences:

# Input: an array 
# Output: a non-empty stream of non-negative integers 
def differences: 
    def abs: if . < 0 then - . else . end; 
    map(select(. != null)) 
    | if length == 0 then 0 
    elif length == 1 then (.[0]|abs) 
    else range(1;length) as $i | (.[$i] - .[$i - 1]) | abs end; 

Man könnte dies dann verwenden wie so:

map({box_id, sumAD: ([.number_items | differences] | add) }) 

Allerdings wäre es besser, (von einem Speichernutzung Standpunkt aus) sich die Tatsache zunutze zu tragen, dass differences gibt einen Stream aus:

def sigma(s): reduce s as $x (0; . + $x); 
map({box_id, sumAD: (sigma(.number_items | differences)) }) 
Verwandte Themen