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

158
Vistas
Detecting JSON Subschema in JavaScript

My JSON could have "n" layers of subschema - How can I detect if a key has a subschema under it to prevent if from looping incorrectly as it's doing today? As you can see in my code below I am starting to consider moving the subschemas to arrays, but this feels like a workaround, not the correct approach. Lastly, is it possible to avoid multiple FOR loops to better handle the "n" layers of subschema.

jsfiddle

HTML

<table></table>

Javascript

var data = {
  "THREE LEVEL": {
    "PRODUCTION": {
      "One": "http://one.com",
      "Two": "http://two.com"
    },
    "LATEST": {
      "alpha": "http://alpha.com",
      "omega": "http://omega.com"
    },
    "STAGE": {
      "Apha": "http://alpha.com",
      "Bravo": "http://bravo.com", 
      "Charley": "http://charley.com"
    }
  },
  "TWO LEVEL": {
    "PRODUCTION": "http://aaa.com",
    "LATEST": "http://bbb.com",
    "STAGE": "http://ccc.com"
  }
}

var table = document.querySelector('table');
var rows = '';

for (var lev_1 in data) {
  rows += '<tr><td>' + lev_1 + '</td><td></td></tr>'
  //if(Array.isArray(data[lev_1])){
    for (var lev_2 in data[lev_1]) {
      rows += '<tr><td><a href="' + data[lev_1][lev_2] + '">' + lev_2 + '</td><td></td></tr>'
      //if(Array.isArray(data[lev_1][lev_2])) {
        for (var lev_3 in data[lev_1][lev_2]) {
          rows += '<tr><td><a href="' + data[lev_1][lev_2][lev_3] + '">' + lev_3 + '</td><td></td></tr>'
        }
      //}
    }  
  //}
}
table.innerHTML = rows;

Current Output

THREE LEVEL 
PRODUCTION  
One 
Two 
LATEST  
alpha   
omega   
STAGE   
Apha    
Bravo   
Charley 
TWO LEVEL   
PRODUCTION  
0   
1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
LATEST  
0   
1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
STAGE   
0   
1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

Use typeof() to determine what kind of element you're dealing with.

  • If its an object then use Object.keys() to get an array of all of the keys within the object. Then iterate through the keys, testing each with typeof()...

  • If it's an array, then iterate through each element of the array testing each with typeof()

  • Rinse and repeat.

The following example should give you a better idea of how to proceed.

var data = {
  "THREE LEVEL": {
    "PRODUCTION": {
      "One": "http://one.com",
      "Two": "http://two.com"
    },
    "LATEST": {
      "alpha": "http://alpha.com",
      "omega": "http://omega.com"
    },
    "STAGE": {
      "Apha": "http://alpha.com",
      "Bravo": "http://bravo.com",
      "Charley": "http://charley.com"
    }
  },
  "TWO LEVEL": {
    "PRODUCTION": "http://aaa.com",
    "LATEST": "http://bbb.com",
    "STAGE": "http://ccc.com"
  }
}

var table = document.querySelector('table');
var rows = '';

var iterateObject = function(dataObject) {
  var keys = Object.keys(dataObject);
  keys.forEach(function(key) {
    var textArray = [];
    var element = dataObject[key];
    switch (typeof(element)) {
      case 'object':
        textArray.push(key)
        dumpRow(textArray);
        iterateObject(element);
        break;
      case 'array':
        textArray.push(key)
        dumpRow(textArray);
        iterateArray(element);
        break;
      default:
        dumpElement(dataObject, key);
        break;
    }
  });
};

var iterateArray = function(dataArray) {
  dataArray.forEach(function(element) {
    switch (typeof(element)) {
      case 'object':
        iterateObject(element);
        break;
      case 'array':
        iterateArray(element);
        break;
      default:
        var textArray = [];
        textArray.push(element)
        dumpRow(textArray);
        break;
    }
  });
};

var dumpElement = function(obj, key) {
  var textArray = [];
  textArray.push(key);
  textArray.push(obj[key]);
  dumpRow(textArray);
};

var dumpRow = function(textArray) {
  var dumpString = '<tr>';
  textArray.forEach(function(text) {
    dumpString += dumpCell(text);
  });
  dumpString += '</tr>';
  rows += dumpString;
};

var dumpCell = function(dumpText) {
  var dumpString = '<td>';
  dumpString += dumpText;
  dumpString += '</td>';
  return dumpString;
};

switch (typeof(data)) {
  case 'object':
    iterateObject(data);
    break;
  case 'array':
    iterateArray(data);
    break;
  default:
    var textArray = [];
    textArray.push(data)
    dumpRow(textArray);
    break;
}

table.innerHTML = rows;
<html>

<body>
</body>
<table>
</table>

</html>

about 4 years ago · Juan Pablo Isaza Denunciar

0

You should probably make some kind of TableMaker:

//<![CDATA[
/* js/external.js */
let doc, htm, bod, nav, M, I, mobile, S, Q, TableMaker; // for use on other loads
addEventListener('load', () => {
  doc = document;
  htm = doc.documentElement;
  bod = doc.body;
  nav = navigator;
  M = tag => doc.createElement(tag);
  I = id => doc.getElementById(id);
  mobile = /Mobi/i.test(nav.userAgent);
  S = (selector, within) => {
    let w = within || doc;
    return w.querySelector(selector);
  }
  Q = (selector, within) => {
    let w = within || doc;
    return w.querySelectorAll(selector);
  }
  TableMaker = function(object) {
    this.table = M('table');
    this.thead = M('thead');
    this.tbody = M('tbody');
    this.tfoot = M('tfoot');
    this.trMake = () => {
      return M('tr');
    }
    this.thMake = textContent => {
      const th = M('th');
      th.textContent = textContent;
      return th;
    }
    this.tdMake = textContent => {
      const td = M('td');
      td.textContent = textContent;
      return td;
    }
    if (object !== undefined) {
      let tr, o, n, td;
      for (let k in object) {
        tr = this.trMake();
        if (typeof k === 'string') {
          tr.appendChild(this.tdMake(k));
          this.tbody.appendChild(tr);
          o = object[k];
          if (typeof o === 'string') {
            tr.appendChild(this.tdMake(o));
          } else {
            n = new TableMaker(object[k]);
            td = this.tdMake();
            td.appendChild(n.table);
            tr.append(td);
          }
        }
      }
    }
    this.table.appendChild(this.thead);
    this.table.appendChild(this.tbody);
    this.table.appendChild(this.tfoot);
  }
  // magic below can be put on a separate page - except // end load line
  var data = {
    "THREE LEVEL": {
      "PRODUCTION": {
        "One": "http://one.com",
        "Two": "http://two.com"
      },
      "LATEST": {
        "alpha": "http://alpha.com",
        "omega": "http://omega.com"
      },
      "STAGE": {
        "Apha": "http://alpha.com",
        "Bravo": "http://bravo.com",
        "Charley": "http://charley.com"
      }
    },
    "TWO LEVEL": {
      "PRODUCTION": "http://aaa.com",
      "LATEST": "http://bbb.com",
      "STAGE": "http://ccc.com"
    }
  }
  const tM = new TableMaker(data);
  bod.appendChild(tM.table);
}); // end load
//]]>
table {
  border: 1px solid #000;
}

td {
  border: 1px solid #090;
}

You'll notice I've included a small library, as well. Note the recursive nature of TableMaker.

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