2017-10-19 4 views
1

Ich habe ein Array von Objekten, und ich möchte einige Duplikate in diesem Array entfernen, ich möchte aber die Anzahl der Duplikate behalten.Zählen und Entfernen von Duplikaten in jq

Meine Eingabe ist:

[ 
    { 
     "foo": 1, 
     "bar": "a", 
     "baz": "whatever" 
    }, 
    { 
     "foo": 1, 
     "bar": "a", 
     "baz": "hello" 
    }, 
    { 
     "foo": 1, 
     "bar": "b", 
     "baz": "world" 
    } 
] 

(nicht sicher, ob es wichtig ist, aber die Einzigartigkeit eines Objekts basiert auf foo und bar, nicht baz

Ein Beispiel für gewünschte Ausgabe wäre dann.:

[ 
    { 
     "foo": 1, 
     "bar": "a", 
     "baz": "whatever", 
     "count": 2 
    }, 
    { 
     "foo": 1, 
     "bar": "b", 
     "baz": "world", 
     "count": 1 
    } 
] 

oder sogar:

[ 
    { 
     "count": 2, 
     "data": { 
      "foo": 1, 
      "bar": "a", 
      "baz": "whatever" 
     } 
    }, 
    ... 
] 

Ich weiß, wie man den Eindeutigkeitsteil (mit) aber nicht den zählenden Teil tut.

Antwort

1

können Sie den folgenden Befehl auf group_by Basis verwenden:

group_by(.foo,.bar) 
| map(.[]+{"count":length}) 
| unique_by(.foo,.bar) 

Ausgang:

[ 
    { 
    "foo": 1, 
    "bar": "a", 
    "baz": "whatever", 
    "count": 2 
    }, 
    { 
    "foo": 1, 
    "bar": "b", 
    "baz": "world", 
    "count": 1 
    } 
] 

Die andere Ausgabe, die Sie erwähnt mit diesem Befehl erreicht werden:

group_by(.foo,.bar) 
| map({"count":length,"data":(unique_by(.foo,.bar)[])}) 

Ausgang :

[ 
    { 
    "count": 2, 
    "data": { 
     "foo": 1, 
     "bar": "a", 
     "baz": "whatever" 
    } 
    }, 
    { 
    "count": 1, 
    "data": { 
     "foo": 1, 
     "bar": "b", 
     "baz": "world" 
    } 
    } 
] 
+0

Danke, es funktioniert! Für die zweite Ausgabe wäre es nicht einfacher, "Daten" zu machen: Erstens? – GrecKo

+0

Ja, kann auch verwendet werden. Und wäre einfacher! – hek2mgl

+0

Oh ja! Entfernt. – hek2mgl

1

Hier ist eine Lösung, die Sortierung peak ‚s GROUPS_BY statt group_by/1 zu vermeiden verwendet:

def GROUPS_BY(stream; f): reduce stream as $x ({}; .[$x|f] += [$x]) | .[] ; 

    GROUPS_BY(.[]; {foo,bar}|tostring) 
| .[0].count = length 
| .[0]