Данная задача в принципе не решается сортировкой, так как сортировка это про отношение больше/меньше/равно, которого в данном случае нет.
Самое простое здесь, это построить из этих элементов двусвязный список, а затем преобразовать его в результирующий массив:
function orderArray(arr) {
// для начала построим ноды списка и соберем их в 2 HashMap по обоим строкам
const maps = arr.reduce((acc, item) => {
const node = {item, next: null, prev: null};
acc[0][item[0]] = node;
acc[1][item[1]] = node;
return acc;
}, [{}, {}]);
// после пройдемся по обоим HashMap и соединим связи
for(const key of Object.keys(maps[0])) {
maps[0][key].next = maps[0][maps[0][key].item[1]] || null;
}
for(const key of Object.keys(maps[1])) {
maps[1][key].prev = maps[1][maps[1][key].item[0]] || null;
}
// найдем начальную ноду списка (ноду без предыдущей ноды)
let cur = Object.values(maps[0]).find(({prev}) => prev === null);
// и начиная с нее соберем список в массив
const result = [];
while(cur) {
result.push(cur.item);
cur = cur.next;
}
return result;
}
console.log(orderArray([['butter', 'jelly'], ['bananas', 'apples'], ['peanuts', 'butter'], ['jelly', 'bananas']]));