Преобразования JSON в таблицу HTML

Просьба, подсказать, как корректно перебрать подобную json конструкцию для формирования html таблицы

const response = {"ab":{"0":"1","1":"2","2":"3","3":"4","4":"5","5":"6","6":"7","7":"8"},
                "ac":{"0":"1","1":"2","2":"3","3":"4","4":"5","5":"6","6":"7","7":"8"},
                "ad":{"0":"1","1":"2","2":"3","3":"4","4":"5","5":"6","6":"7","7":"8"},
                "af":{"0":"1","1":"2","2":"3","3":"4","4":"5","5":"6","6":"7","7":"8"},
                "ar":{"0":"1","1":"2","2":"3","3":"4","4":"5","5":"6","6":"7","7":"8"},
                "ae":{"0":"1","1":"2","2":"3","3":"4","4":"5","5":"6","6":"7","7":"8"},
                "ac":{"0":"1","1":"2","2":"3","3":"4","4":"5","5":"6","6":"7","7":"8"}}

на выходе получить

<table>
        <thead>
            <tr>
                <td>ab</td>
                <td>ac</td>
                <td>ad</td>
                <td>af</td>
                <td>ar</td>
                <td>ae</td>
                <td>ac</td>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>1</td>
                <td>1</td>
                <td>1</td>
                <td>1</td>
                <td>1</td>
                <td>1</td>
                <td>1</td>
            </tr>
            <tr>
                <td>2</td>
                <td>2</td>
                <td>2</td>
                <td>2</td>
                <td>2</td>
                <td>2</td>
                <td>2</td>
            </tr>
        </tbody>
    </table>

пробовал подобным способом, но возвращает только одну строку в таблицу:

const tr = document.createElement('tr');
const value = Object.values(response);

value.forEach((key, item) => {
    
    console.log(key[item]);
    $(tr).append('<td>'+key[item]+'</td>');
    
})
console.log(tr)
$('tbody').append(tr)

Ответы (1 шт):

Автор решения: yar85

const response = {
  "ab": { "0":"1","1":"2","2":"3","3":"4","4":"5","5":"6","6":"7","7":"8" },
  "ac": { "0":"1","1":"2","2":"3","3":"4","4":"5","5":"6","6":"7","7":"8" },
  "ad": { "0":"1","1":"2","2":"3","3":"4","4":"5","5":"6","6":"7","7":"8" },
  "af": { "0":"1","1":"2","2":"3","3":"4","4":"5","5":"6","6":"7","7":"8" },
  "ar": { "0":"1","1":"2","2":"3","3":"4","4":"5","5":"6","6":"7","7":"8" },
  "ae": { "0":"1","1":"2","2":"3","3":"4","4":"5","5":"6","6":"7","7":"8" },
};

// преобразование столбцов в строки, и извлечение заголовков
const tableData = { headers: Object.keys(response), rows: [] };
for (const header of tableData.headers) {
  Object.values(response[header]).forEach((val, idx) => {
    (tableData.rows[idx] = (tableData.rows[idx] ?? [])).push(val);
  });
}
// рендеринг таблицы
const tBody = document.createElement('table').createTBody();
tBody.insertAdjacentHTML('beforeBegin', `<thead><tr>${
  tableData.headers.map(hdr => `<th>${hdr}</th>`).join('')
}</tr></thead>`);
for (const row of tableData.rows) {
  const tr = tBody.insertRow();
  row.forEach(val => tr.insertCell().textContent = val);
}
document.body.appendChild(tBody.parentElement);
table  { border-collapse: collapse; }
th, td { min-width: 3ch; padding: 0.25em 0.5em; border: 1px solid #ccc; }

В литерале объекта response убрал дублирующееся свойство ac - потому что в результате имеет значение только самое последнее объявление свойства (предыдущие объявления с тем же именем свойства "игнорируются").


Если не нравится ES11+, то оператор ?? тут можно безболезненно заменить на ||. В остальном, используются возможности уже старенького ES6 (for..of, стрелочные функции, шаблонные строки).

→ Ссылка