Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

318
Visualizações
¿Cómo encontrar todos los nodos y sus vínculos con otros nodos atravesándolos en ambas direcciones (padres e hijos)?

Tengo una aplicación cliente que consume datos de una API externa basada en una configuración durante el inicio.

Dado que calcular los datos necesarios no es fácil para mí, intenté falsificar la implementación y calcularla localmente por ahora.

Hay muchos WorkItems vinculados entre sí y la configuración solo conoce las relaciones a considerar.


Algunas explicaciones:

Elemento de trabajo

Un elemento de trabajo tiene una identificación única y un tipo

p.ej

 { id: 1, type: "person" }

para que sepa que Workitem 1 es de tipo persona

Rol de enlace

Un linkrole es una clave compuesta de tres claves

  • El tipo de elemento de trabajo principal
  • El tipo de elemento de trabajo secundario
  • El nombre del papel

p.ej

 { parentWorkItemType: "person", childWorkItemType: "house", name: "owns", }

que representa Persona propietaria de Casa

Enlaces

El backend conoce las relaciones, un enlace entre los elementos de trabajo podría verse como

 { /* each link is unique */ linkRole: { parentWorkItemType: "person", childWorkItemType: "house", name: "owns", }, parentId: 1, childId: 2 }

entonces sabes que la Persona 1 es dueña de la Casa 2


Requisitos falsos:

Back-end falso

Creé algunos datos falsos para mis cálculos. El archivo backend.js representa el backend/base de datos

 // backend.js export const workItems = [{ id: 1, type: "car" }, { id: 2, type: "car" }, { id: 3, type: "bird" }, { id: 4, type: "bird" }, { id: 5, type: "bird" }, { id: 6, type: "invalid" }, { id: 7, type: "house" }, { id: 8, type: "house" }, { id: 9, type: "house", }, { id: 10, type: "person", }]; export const workItemLinks = [{ linkRole: { parentWorkItemType: "car", childWorkItemType: "bird", name: "isChildOf", }, parentId: 1, childId: 3 }, { linkRole: { parentWorkItemType: "car", childWorkItemType: "bird", name: "isChildOf", }, parentId: 1, childId: 4 }, { linkRole: { parentWorkItemType: "bird", childWorkItemType: "house", name: "with", }, parentId: 3, childId: 7 }, { linkRole: { parentWorkItemType: "bird", childWorkItemType: "house", name: "with", }, parentId: 3, childId: 8 }, { linkRole: { parentWorkItemType: "person", childWorkItemType: "car", name: "owns", }, parentId: 10, childId: 1 }, { linkRole: { parentWorkItemType: "car", childWorkItemType: "car", name: "references", }, parentId: 1, childId: 2 }];

API falsa

Creé algunos métodos dentro del archivo api.js para falsificar una API que solicita datos al backend.

Nota al margen importante: estos métodos solo me ayudan a encontrar los datos que necesito. Puedo agregar más "ayudantes" si es necesario (en el mundo real, puedo solicitar agregar más puntos finales de API) para que todo se pueda consultar. No dude en modificar la "API falsa".

 // api.js import { workItems, workItemLinks } from "./backend.js"; export function getWorkItemsByType(workItemType) { return workItems.filter(workItem => workItem.type === workItemType); } export function getWorkItemsByIds(workItemIds) { return workItems.filter(workItem => workItemIds.some(workItemId => workItemId === workItem.id)); } export function getWorkItemLinksByLinkRoleAndLeftSideIds(linkRole, leftSideIds, leftSideIsParentSide) { return workItemLinks.filter(workItemLink => { // Pseudo equality check if (workItemLink.linkRole.parentWorkItemType === linkRole.parentWorkItemType && workItemLink.linkRole.childWorkItemType === linkRole.childWorkItemType && workItemLink.linkRole.name === linkRole.name) { const leftSideIdInLink = leftSideIsParentSide ? workItemLink.parentId : workItemLink.childId; // Return this link if it matches with the left side id ( you're looking for the right side id ) return leftSideIds.some(leftSideId => leftSideId === leftSideIdInLink); } return false; }); }

Configuración falsa

Creé definiciones dentro de configuration.js para iniciar los cálculos basados en esos

 // configuration.js export const definitions = [ { // fetch linked birds from every root car linkRole: { parentWorkItemType: "car", childWorkItemType: "bird", name: "isChildOf", } }, { // !! Root Element !! Fetch work items based on type workItemType: "car", isRootWorkItem: true }, { // fetch linked houses from every bird ( car - bird - house ) linkRole: { parentWorkItemType: "bird", childWorkItemType: "house", name: "with", } }, { // fetch every person from every car ( person - car ) linkRole: { parentWorkItemType: "person", childWorkItemType: "car", name: "owns", } }, { // Self reference, fetch linked cars from every root car linkRole: { parentWorkItemType: "car", childWorkItemType: "car", name: "references", } }, ];

Problema a resolver:

Estoy buscando una forma eficaz de obtener todos los enlaces y elementos de trabajo relacionados desde el backend en función de la cadena de relaciones que comienza con cada elemento raíz.

Salida esperada basada en la configuración:

 export const workItems = [{ id: 1, type: "car" }, { id: 2, type: "car" }, { id: 3, type: "bird" }, { id: 4, type: "bird" }, /* no car is linked to bird 5, no links for invalid 6 */ { id: 7, type: "house" }, { id: 8, type: "house" }, /* no bird is linked to house 9 */ { id: 10, type: "person", }]; /* based on the configuration every workItemLink from the backend got fetched */

Mi primer enfoque de implementación:

 import { inspect } from "util"; import { getWorkItemsByType, getWorkItemsByIds, getWorkItemLinksByLinkRoleAndLeftSideIds } from "./api.js"; import { definitions } from "./configuration.js"; // Find the root definition const { workItemType: rootWorkItemType } = definitions.find(definition => definition.isRootWorkItem); // Fetch all the root workitems and initialize the store holding unique workitems const workItems = getWorkItemsByType(rootWorkItemType); // will hold car 1 and car 2 const initialWorkItemIds = workItems.map(workItem => workItem.id); const workItemIdsToLoad = []; // try to read all missing ids from fetched links and fetch all the workitems at once later on const workItemLinks = []; // global store for links const definitionsToTraverse = definitions.filter(definition => definition.linkRole !== undefined); // do not consider the root definition run(initialWorkItemIds, rootWorkItemType, definitionsToTraverse, workItemIdsToLoad, workItemLinks); const missingWorkItemIdsToLoad = workItemIdsToLoad.filter(workItemIdToLoad => !rootWorkItemIds.some(rootWorkItemId => rootWorkItemId === workItemIdToLoad)); // filter out all the existing root item ids const workItemsToAdd = getWorkItemsByIds(missingWorkItemIdsToLoad); // fetch all the missing workitems at once workItems.push(...workItemsToAdd); // add them to the global store console.log(inspect({ workItems, workItemLinks }, false, null, true)) function run(leftSideWorkItemIds, leftSideWorkItemType, definitionsToTraverse, workItemIdsToLoad, workItemLinks) { /* consider all the defitions from "definitionsToTraverse" directly related to "leftSideWorkItemType" remove them from "definitionsToTraverse" to prevent endless loops loop backwards so splice won't struggle with the indices */ for (let definitionIndex = definitionsToTraverse.length - 1; definitionIndex >= 0; definitionIndex--) { const currentDefinition = definitionsToTraverse[definitionIndex]; const { linkRole } = currentDefinition; const { parentWorkItemType, childWorkItemType } = linkRole; const leftSideWorkItemTypeIsParent = parentWorkItemType === leftSideWorkItemType; const leftSideWorkItemTypeIsChild = childWorkItemType === leftSideWorkItemType; // Check the direct relation if (leftSideWorkItemTypeIsParent || leftSideWorkItemTypeIsChild) { // Remove the inspected definition definitionsToTraverse.splice(definitionIndex, 1); const relatedWorkItemLinks = getWorkItemLinksByLinkRoleAndLeftSideIds(linkRole, leftSideWorkItemIds, leftSideWorkItemTypeIsParent); // store all the right side workitem IDs for the next run const rightSideWorkItemIds = []; for (let relatedWorkItemLinkIndex = 0; relatedWorkItemLinkIndex < relatedWorkItemLinks.length; relatedWorkItemLinkIndex++) { const relatedWorkItemLink = relatedWorkItemLinks[relatedWorkItemLinkIndex]; // Process the link if not processed yet if (!workItemLinks.some(workItemLink => /* !!! pseudo equality check !!! */ workItemLink.linkRole.parentWorkItemType === relatedWorkItemLink.linkRole.parentWorkItemType && workItemLink.linkRole.childWorkItemType === relatedWorkItemLink.linkRole.childWorkItemType && workItemLink.linkRole.name === relatedWorkItemLink.linkRole.name && workItemLink.parentId === relatedWorkItemLink.parentId && workItemLink.childId === relatedWorkItemLink.childId)) { // Push the link to the store workItemLinks.push(relatedWorkItemLink); // Get the right side id from the link const rightSideWorkItemId = leftSideWorkItemTypeIsParent ? relatedWorkItemLink.childId : relatedWorkItemLink.parentId; rightSideWorkItemIds.push(rightSideWorkItemId); // Push the id to the store if it doesn't exist if (!workItemIdsToLoad.some(workItemIdToLoad => workItemIdToLoad === rightSideWorkItemId)) { workItemIdsToLoad.push(rightSideWorkItemId); } } } // Find the opposite workitem type of the current definition const rightSideWorkItemType = leftSideWorkItemTypeIsParent ? childWorkItemType : parentWorkItemType; // Run again but use this definition as the previous one run(rightSideWorkItemIds, rightSideWorkItemType, definitionsToTraverse, workItemIdsToLoad, workItemLinks); } } }

El problema es que mi enfoque falla porque el bucle hacia atrás incluso se ejecuta si definitionsToTraverse está vacío. Y estoy mutando las matrices de los parámetros directamente, creo que no debería hacer eso.

Así que cualquier ayuda sería muy apreciada!

over 4 years ago · Santiago Trujillo
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda