const arr1 = [{ route: 'x1' }, { route: 'x2' }, { route: 'x3' }, { route: 'x4' }, { route: 'x5' }],
arr2 = [{ pattern: 'y1', route: 'x1' }, { pattern: 'y2', route: 'x1' }, { pattern: 'y3', route: 'x2' }, { pattern: 'y4', route: 'x2' }, { pattern: 'y5', route: 'x3' }, { pattern: 'y6', route: 'x3' }, { pattern: 'y7', route: 'x4' }, { pattern: 'y8', route: 'x4' }, { pattern: 'y9', route: 'x5' }, { pattern: 'y10', route: 'x5' }];
const map = new Map(arr2.map( o => [o.route, []] ));
for (const o of arr2) map.get(o.route).push(o.pattern);
const table = document.querySelector('.tg');
for (const [route, patterns] of map) {
const row = table.insertRow();
row.insertCell().textContent = route;
row.insertCell().textContent = patterns.join(', ');
}
.tg {border-collapse:collapse;border-spacing:0;}
.tg td{font-family:Arial, sans-serif;font-size:14px;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;}
.tg th{font-family:Arial, sans-serif;font-size:14px;font-weight:normal;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;}
.tg .tg-yw4l{vertical-align:top}
<table class="tg">
<tr>
<th class="tg-yw4l">ROUTE</th>
<th class="tg-yw4l">PATTERN(s)</th>
</tr>
</table>