Это продолжение более раннего вопроса. Спасибо @harshank за быструю помощь. Я публикую этот вопрос отдельно, так как требовалась дополнительная проверка, которую я не задавал в предыдущем вопросе. Таким образом, решение, опубликованное ранее, отлично подходит для заявленного требования.
Я добавляю дополнительное требование здесь:
Решение о совпадении gp
и parent
зависит от дополнительного атрибута eye_colour
(см. образец полезной нагрузки ниже).
Также в ответе необходимо заполнить дополнительные поля (о чем не упоминалось в предыдущем вопросе). Такие вещи, как name
и eye_colour
.
Итак, в качестве примера это полезная нагрузка:
[
{
"gp": "T1",
"gp_eye_colour": "blue",
"gp_name" : "John",
"parent": "T1",
"parent_eye_colour" : "black",
"parent_name" : "Sam",
"child": "C1",
"child_eye_colour" : "brown",
"child_name" : "C1"
},
{
"gp": "T1",
"gp_eye_colour": "blue",
"gp_name" : "John",
"parent": "T1",
"parent_eye_colour" : "black",
"parent_name" : "Sam",
"child": "C1",
"child_eye_colour" : "brown",
"child_name" : "C1"
}
]
И теперь, используя более раннее решение, я попытался построить его поверх него как:
%dw 2.0
output application/xml
// hierarchy's structure. If, lets say you add a "grand child" it should work. (haven't tested this though)
var hierarchy = {
gp: {
parent: {
child: null
}
}
}
fun getDirectGeanologies(records, hierarchyStructure,isGp,isParent,isChild) = do {
var topLevel = keysOf(hierarchyStructure)[0] as String
var secondLevel = keysOf(hierarchyStructure[topLevel])[0]
---
(records groupBy $[topLevel])
mapObject ((level1Childs, code) ->
genealogy: {
code: code,
eye_colour: if (isGp) (level1Childs.gp_eye_colour) else if (isParent) (level1Childs.parent_eye_colour) else (level1Childs.child_eye_colour),
name: if (isGp) (level1Childs.gp_name) else if (isParent) (level1Childs.parent_name) else (level1Childs.child_name),
hierarchy:
if (secondLevel != null) // If there are no more childs, do nothing.
(level1Childs groupBy ((item) -> item[secondLevel] ~= code) // This is to handle when parent = gp
mapObject ((value, hasSameParent) ->
// If parent = gp, we want to skip parent and link directly to child
if (hasSameParent as Boolean) getDirectGeanologies(value, hierarchyStructure[topLevel][secondLevel],false,false,true)
// recurrsively call the function with child records and going down the hierarchyStructure by one
else getDirectGeanologies(value, hierarchyStructure[topLevel],false,true,false)
))
else {}
}
)
}
---
list: getDirectGeanologies(payload,hierarchy,true,false,false)
Однако он генерирует повторяющиеся элементы для eye_colour
и name
. В идеале он должен печатать значения только один раз со значением либо gp/parent/child.
Это ожидаемый ответ:
<?xml version='1.0' encoding='UTF-8'?>
<list>
<genealogy>
<code>T1</code>
<eye_colour>blue</eye_colour>
<name>John</name>
<hierarchy>
<genealogy>
<code>C1</code>
<eye_colour>brown</eye_colour>
<name>C1</name>
<hierarchy/>
</genealogy>
</hierarchy>
</genealogy>
</list>
Я также не смог понять, как проверить, имеют ли gp и parent одинаковые значения на основе двух полей (gp & gp_eye_colour
vs parent & parent_eye_colour
)
Спасибо @sudhish_s за ответ, добавив пример для уточнения решения о том, когда пропустить родителя (когда gp & gp_eye_colour
gp совпадает с parent & parent_eye_colour
родителя).
Пример ввода: (Здесь родитель Sam
не следует пропускать, поскольку, хотя gp и родитель одинаковы, их цвета глаз различаются. Аналогично, в случае Don
этот родитель следует пропустить, поскольку gp и родитель и их цвета глаз одинаковы).
[
{
"gp": "T1",
"gp_eye_colour": "blue",
"gp_name" : "John",
"parent": "T1",
"parent_eye_colour" : "black",
"parent_name" : "Sam",
"child": "C1",
"child_eye_colour" : "brown",
"child_name" : "C1"
},
{
"gp": "T1",
"gp_eye_colour": "blue",
"gp_name" : "John",
"parent": "T1",
"parent_eye_colour" : "blue",
"parent_name" : "Don",
"child": "C1",
"child_eye_colour" : "brown",
"child_name" : "C1"
}
]
Вот ожидаемый ответ:
<?xml version='1.0' encoding='UTF-8'?>
<list>
<genealogy>
<code>T1</code>
<eye_colour>blue</eye_colour>
<name>John</name>
<hierarchy>
<genealogy>
<code>T1</code>
<eye_colour>black</eye_colour>
<name>Sam</name>
<hierarchy>
<genealogy>
<code>C1</code>
<eye_colour>brown</eye_colour>
<name>C1</name>
<hierarchy/>
</genealogy>
</hierarchy>
</genealogy>
<genealogy>
<code>C1</code>
<eye_colour>brown</eye_colour>
<name>C1</name>
<hierarchy/>
</genealogy>
</hierarchy>
</genealogy>
</list>
Немного другая версия. Используемые массивы для справки.
%dw 2.0
output application/xml
var hierarchy = ["gp", "parent", "child"]
fun getDirectGeanologies(records, level) = do {
var hLevel = hierarchy[level]
---
records groupBy $[hLevel] mapObject ((children, code) ->
genealogy: {
code: code,
eye_colour: children[0][hLevel ++ "_eye_colour"],
name: children[0][hLevel ++ "_name"],
hierarchy:
if (level == sizeOf(hierarchy) - 1) {}
else do {
var nextLevel = level + 1
var nextGen = children groupBy ($[hierarchy[nextLevel]])
---
nextGen mapObject ((nextGenChildren, nextGenCode) ->
if (nextGenCode == code)
getDirectGeanologies (nextGenChildren, nextLevel + 1 )
else
getDirectGeanologies (nextGenChildren, nextLevel)
)
}
}
)
}
---
list: getDirectGeanologies(payload,0)
Проблема с элементами, которые появляются несколько раз, связана с тем, что level1Childs
— это массив. Измените вывод на json
, будет понятнее. Если вы хотите использовать свой код, измените сопоставление eye_colour
и name
на приведенное ниже.
eye_colour: if (isGp) (level1Childs[0].gp_eye_colour) else if (isParent) (level1Childs[0].parent_eye_colour) else (level1Childs[0].child_eye_colour),
name: if (isGp) (level1Childs[0].gp_name) else if (isParent) (level1Childs[0].parent_name) else (level1Childs[0].child_name),
Спасибо @sudhish_s за это, с небольшими изменениями удалось добиться желаемого результата, спасибо!