<table border>
<thead>
<td>ПН</td>
<td>ВТ</td>
<td>СР</td>
<td>ЧТ</td>
<td>ПТ</td>
<td>СБ</td>
<td>ВС</td>
</thead>
<tr id="state">
<td>Выходной</td>
<td>Выходной</td>
<td>Выходной</td>
<td>Выходной</td>
<td>15-21</td>
<td>15-21</td>
<td>16-21</td>
</tr>
</table>
var
$Table = $("<table />"),
$Thead = $("<thead />").appendTo($Table),
$Row = $("<tr />").appendTo($Table),
$_tds = $("#state td"), $_heads = $("thead td"),
start, i = 0;
for(; i < $_tds.length; i++){
start = i;
while(
$_tds.get(i++) && $_tds.eq(i).text() == $_tds.eq(i - 1).text()
){}
$Row.append(
"<td>" + $_tds.eq(--i).text() + "</td>"
);
$Thead.append(
"<td>" + (i == start ? "" : $_heads.eq(start).text() + "-") + $_heads.eq(i).text() + "</td>"
);
}
$("table").replaceWith($Table);
function mergeCells(table) {
var head = table.rows[0],
body = table.rows[1],
resultHead = "",
resultBody = "",
matches = {};
for (var i = 0; i < body.cells.length; i++) {
var headCellText = head.cells[i].textContent,
bodyCellText = body.cells[i].textContent,
match = matches[bodyCellText] || (matches[bodyCellText] = []);
match.push(headCellText);
}
for (var key in matches) {
var match = matches[key],
from = match[0],
to = match[match.length - 1];
if (match.length > 1) {
resultHead += "<td>" + from + "-" + to + "</td>";
} else {
resultHead += "<td>" + from + "</td>";
}
resultBody += "<td>" + key + "</td>";
}
head.innerHTML = resultHead;
body.innerHTML = resultBody;
}