Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

104
Vistas
How do I parse the indentation level of a string into a JSON Object?

I'd like to be able to parse a string into a JSON Object, something like this (the text can be anything, I'm just putting them like this so you can see the structure):

A
  A-A
  A-B
    A-B-A
    A-B-B
  A-C
    A-C-A
B

into a json object, structured like this:

[
  {
    "root": "A",
    "content": [
      { "root": "A-A", "content": [] },
      {
        "root": "A-B",
        "content": [
          { "root": "A-B-A", "content": [] },
          { "root": "A-B-B", "content": [] }
        ]
      },
      {
        "root": "A-C",
        "content": [
          { "root": "A-C-A", "content": [] }
        ]
      }
    ]
  },
  { "root": "B", "content": [] }
]

So far, I have the following, but I'm not sure if this is the best way of doing it. Maybe a recursive approach would be better?

  let body = [];
  let indentStack = [0];
  for (let line of input.split('\n')) { // input is the string I'd like to parse
    if (line.trim() == '') continue; // skips over empty lines
    let indent = line.match(/^ +/);
    indent = indent ? indent[0].length : 0; // matches the first group of spaces with regex, gets the indent level of this line
    if (indentStack[indentStack.length-1] != indent) 
      if (indentStack.includes(indent)) indentStack.length = indentStack.indexOf(indent)+1; // remove all indent levels after it as it's returned back to a higher level
      else stack.push(indent);
    console.log(`${(indent + '[' + indentStack.join() + ']').padEnd(10, ' ')}: ${line}`); // debugging
      
    if (indentStack.length == 1) body.push({ root: line, content: [] });
    else {
      body[body.length-1].content.push({ root: line.substring(indent), content: [] })
    }
  }
  console.log(body)
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

I will do that this way :

const data =
`A
  A-A
  A-B
    A-B-A
    A-B-B
  A-C
    A-C-A
B`;


function doTree(data)
  {
  let
    res    = []
  , levels = [ res ]
    ;
  for (let line of data.split('\n'))  
    {      
    let 
      level   = line.search(/\S/) >> 1  // (index of first non whitespace char) / 2 --> IF indentation is 2 spaces
    , root    = line.trim()
    , content = []
      ;
    if (!root) continue
    levels[level].push({root,content})
    levels[++level] = content
    }
  return res
  }

console.log( doTree(data) )
.as-console-wrapper {max-height: 100%!important;top:0 }

The question about indentations ...

here you can have unequal indentation steps,
either with spaces or with tabs.
(do not mix spaces and tabs)

const data_023c = // indentation values are 0c, 2c, 3c
`A
  A-A
  A-B
     A-B-A
     A-B-B
  A-C
     A-C-A
B`;

const indentation= (()=>  // IIFE 
  {
  let 
    indents = []
  , max     = -1
    ;
  return {
    clear:() => 
      {
      indents.length = 0
      max  = -1
      }
  , get:(line, lNum='?' ) =>
      {
      let ncBefore = line.search(/\S/)

      let level = indents.indexOf(ncBefore)
      if (level===-1)
        {
        if (ncBefore < max) throw `error on indentation,\n line = ${lNum},\n line value is = "${line}"`
        level = indents.push( ncBefore) -1
        max   = ncBefore
        }
      return level
      }
    }
  })()

const doTree = data =>
  {
  let
    res    = []
  , levels = [ res ]
  , lineN  = 0
    ;
  indentation.clear()
  for (let line of data.split('\n'))  
    {
    lineN++  // line counter for indent error message
    let
      root    = line.trim()
    , content = []
      ;
    if (!root) continue
    let level = indentation.get(line, lineN)
     
    levels[level].push({root,content})
    levels[++level] = content
    }
  return res
  }

console.log( doTree(data_023c) )
.as-console-wrapper {max-height: 100%!important;top:0 }

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda