Посмотрите на JS Fiddle: https://jsfiddle.net/d2fL3rhp/
Сначала мы получили уникальные детали level1, level2 и level3, затем после использования $ .each l oop для подготовки требуется HTML тело.
JS код:
let list = [
{category_id: "010103", level1: "electronics", level2: "TV", level3: "samsung"},
{category_id: "010104", level1: "electronics", level2: "TV", level3: "philips"},
{category_id: "010101", level1: "households", level2: "kitchen", level3: "table"},
{category_id: "0101021", level1: "households", level2: "kitchen", level3: "table"},
{category_id: "0101022", level1: "households", level2: "kitchen", level3: "table"},
{category_id: "0101023", level1: "households", level2: "kitchen", level3: "table"},
{category_id: "0101031", level1: "grocery", level2: "abc", level3: "xyz"},
{category_id: "0101032", level1: "grocery", level2: "abc", level3: "pqr"},
{category_id: "0101033", level1: "grocery", level2: "def", level3: "xyz"},
];
let uniqueLevels = {};
if( list != null && list.length > 0 ) {
$.each(list, function(index, value){
if(value.level1 != null && (uniqueLevels[value.level1] == null || typeof uniqueLevels[value.level1] == 'undefined')) {
uniqueLevels[value.level1] = {};
}
if( value.level2 != null && (uniqueLevels[value.level1][value.level2] == null || typeof uniqueLevels[value.level1][value.level2] == 'undefined') ) {
uniqueLevels[value.level1][value.level2] = {};
}
if( value.level3 != null ) {
if(uniqueLevels[value.level1][value.level2][value.level3] == null || typeof uniqueLevels[value.level1][value.level2][value.level3] == 'undefined') {
uniqueLevels[value.level1][value.level2][value.level3] = 1;
}
else {
uniqueLevels[value.level1][value.level2][value.level3] += 1;
}
}
});
}
var tbodyHTML = '';
$.each(uniqueLevels, function(level1_key, level1_data){
$.each(level1_data, function(level2_key, level2_data){
var level2Rows = '', flagAddTR = false, rowspanCount = 0;
$.each(level2_data, function(level3_key, level3_data){
rowspanCount += level3_data;
});
tbodyHTML += '<tr><td rowspan="'+ rowspanCount +'">'+ level1_key +'</td><td rowspan="'+ rowspanCount +'">'+ level2_key +'</td>';
$.each(list, function(key, value){
if( (value['level1'] == level1_key) && (value['level2'] == level2_key) ) {
if( level2Rows != '' ) {
flagAddTR = true;
}
if( flagAddTR ) {
level2Rows += '<tr>';
}
level2Rows += '<td>'+ value['level3'] +'</td><td>'+ value['category_id'] +'</td></tr>';
}
});
tbodyHTML += level2Rows;
});
});
$('#tbody').html(tbodyHTML);