Búsqueda de sitios web

javascript - Encontrar elementos anidados en un objeto Array de Typescript


Tengo un montón de contenido en un arreglo con tipo:

export interface StaticContent {
  level : number,
  id : string,  
  title: string,
  content : string[] | StaticContent[],
}

Estoy tratando de buscar un objeto donde el id a consultar sea un subelemento de un objeto de contenido. Creo que probablemente he configurado mal la interfaz, pero estoy teniendo un bloqueo mental.

¿Alguna idea?

Ejemplo :

data = [
{
  level: 0,
  id: 'first-element',
  title: 'Title of the first element'
  content: [
    `I am some random string of content`
  ]
},
{
  level: 1,
  id: 'second-element',
  title: 'Title of the second element'
  content: [
     {
       level: 0,
       id: 'first-sub-element',
       title: 'Title of first sub element'
       content: [
         ` I am some content attached to the first sub element `
       ]
     }
}]

let idToFind = 'first-sub-element'
let element = data.find(t => t.id === idToFind)
let title = element.title

En este ejemplo el resultado es un elemento indefinido.
Espero

element = {
       level: 0,
       id: 'first-sub-element',
       title: 'Title of first sub element'
       content: [
         ` I am some content attached to the first sub element `
       ]
     }
}

Respuesta #1

Necesitas usar recursión o hacer una búsqueda recursiva en el lugar.

Aquí hay un ejemplo de recursión:

function searchInContent(idToFind: string, content: StaticContent[] | string[]): StaticContent | null {   
    for (const c of content) {
       if (typeof c === 'string') continue
 
       // now we can assume that c is StaticContent
       if (c.id === idToFind) {
          // FOUND RESULT
          return c
       } 
   
       // Perform deep search in content
       const result = searchInContent(idToFind, c.content)
       if (result !== null) {
          // stop searching and pass found result
          return result
       }
    }
    return null
}

let idToFind = 'first-sub-element'
let element = searchInContent(data)
let title = element.title

Respuesta #2

Estás intentando encontrar el objeto content para un id específico. Lo que podrías hacer es flatMap() los contenidos y luego usar find() para encontrar el objeto coincidente correcto.

const data = [{
    level: 0,
    id: 'first-element',
    title: 'Title of the first element',
    content: [
      `I am some random string of content`
    ]
  },
  {
    level: 1,
    id: 'second-element',
    title: 'Title of the second element',
    content: [{
      level: 0,
      id: 'first-sub-element',
      title: 'Title of first sub element',
      content: [
        ` I am some content attached to the first sub element `
      ]
    }, {
      level: 0,
      id: 'first-sub-elemeeent',
      title: 'Title of first sub element',
      content: [
        ` I am some content attached to the first sub element `
      ]
    }]
  }
];

const idToFind = 'first-sub-element';
const result = data.flatMap(d => d.content).find(c => c.id === idToFind);

console.log(result);