Собираем вспомогательный объект вида
{ key: первый индекс, где встречается key }
:
const keyIndex = arr.reduce((acc, n, i) => (acc[n.key] ??= i, acc), {});
Затем выполняем сортировку по двум параметрам, минимальному индексу и
id
. Можно отсортировать существующий массив:
arr.sort((a, b) => (keyIndex[a.key] - keyIndex[b.key]) || (a.id - b.id));
Или собрать отсортированный новый:
const sorted = (arr, keys) => arr
.map(n => [ n ].concat(keys(n)))
.sort((a, b) => {
let diff = 0;
for (let i = 0; ++i < a.length && !(diff = a[i] - b[i]);) ;
return diff;
})
.map(n => n[0]);
const sortedArr = sorted(arr, n => [ keyIndex[n.key], n.id ]);