Вот как я бы подошел к этому:
(ns tst.demo.core
(:use demo.core tupelo.core tupelo.test)
(:require
[clojure.string :as str]
[tupelo.string :as ts]
[tupelo.core :as t]))
(def data-json
"{ 'data': [
{ 'target_group_id': '1234',
'target_group_name': 'abc',
'targets': [
{ 'target_id': '456',
'target_name': 'john' }
]
},
{ 'target_group_id': '56789',
'target_group_name': 'cdes',
'targets': [
{ 'target_id': '0987',
'target_name': 'john' }
]
},
{
'target_group_id': '1234',
'target_group_name': 'abc',
'targets': [
{ 'target_id': '789',
'target_name': 'doe' }
]
}
]
} " )
с преобразованием:
(dotest
(let [data-edn (t/json->edn
(ts/quotes->double data-json))
d2 (t/it-> data-edn
(:data it) ; unnest from :data key
(group-by :target_group_id it ) )
d3 (t/forv [[tgt-id entries] d2]
{:tgt-group-id tgt-id
:tgt-group-name (:target_group_name (first entries))
:targets-all (mapv :targets entries)}) ]
и результатами / тестами:
(is= data-edn
{:data
[{:target_group_id "1234",
:target_group_name "abc",
:targets [{:target_id "456", :target_name "john"}]}
{:target_group_id "56789",
:target_group_name "cdes",
:targets [{:target_id "0987", :target_name "john"}]}
{:target_group_id "1234",
:target_group_name "abc",
:targets [{:target_id "789", :target_name "doe"}]}]})
(is= d2
{"1234"
[{:target_group_id "1234",
:target_group_name "abc",
:targets [{:target_id "456", :target_name "john"}]}
{:target_group_id "1234",
:target_group_name "abc",
:targets [{:target_id "789", :target_name "doe"}]}],
"56789"
[{:target_group_id "56789",
:target_group_name "cdes",
:targets [{:target_id "0987", :target_name "john"}]}]})
(is= d3
[{:tgt-group-id "1234",
:tgt-group-name "abc",
:targets-all [[{:target_id "456", :target_name "john"}]
[{:target_id "789", :target_name "doe"}]]}
{:tgt-group-id "56789",
:tgt-group-name "cdes",
:targets-all [[{:target_id "0987", :target_name "john"}]]}]) ))