Получение иерархии родитель-потомок из массива с использованием DataWeave (дополнительные сведения)

Это продолжение более раннего вопроса. Спасибо @harshank за быструю помощь. Я публикую этот вопрос отдельно, так как требовалась дополнительная проверка, которую я не задавал в предыдущем вопросе. Таким образом, решение, опубликованное ранее, отлично подходит для заявленного требования.

Я добавляю дополнительное требование здесь:

  1. Решение о совпадении gp и parent зависит от дополнительного атрибута eye_colour (см. образец полезной нагрузки ниже).

  2. Также в ответе необходимо заполнить дополнительные поля (о чем не упоминалось в предыдущем вопросе). Такие вещи, как 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>
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
66
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Немного другая версия. Используемые массивы для справки.

%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 за это, с небольшими изменениями удалось добиться желаемого результата, спасибо!

GettingStarted With123 10.02.2023 21:53

Другие вопросы по теме