Как я могу отсортировать массив объектов, содержащий ссылки на другие объекты в том же массиве, который должен стоять первым?
У меня есть массив объектов, которые нужно отсортировать по двум факторы:
- Объект должен появляться после всех его «членов» («члены» являются ссылками на «имя» других объектов в том же массиве).
- Затем, если он не может быть отсортирован по вышеуказанным критериям, он должен быть отсортирован в в алфавитном порядке по «имени» .
Например, рассмотрим следующее MVCE :
const example = [
// This object named "Example 1" should come after its members ("Example 4"):
{
name: 'Example 1',
members: [
'Example 4',
],
},
// This object named "Example 2" should come after its members ("Example 1" and "Example 3"):
{
name: 'Example 2',
members: [
'Example 1',
'Example 3',
],
},
// This object named "Example 3" does not have any members, so it does not necessarily need to change position:
{
name: 'Example 3',
members: [],
},
// This object named "Example 4" does not have any members, so it does not necessarily need to change position:
{
name: 'Example 4',
members: [],
},
// This object named "Example 5" should come after its members ("Example 1"):
{
name: 'Example 5',
members: [
'Example 1',
],
},
];
// The objects in "example" should also be sorted by "name" ASC, where it can not be sorted by "members".
example.sort((a, b) => {
if (a.members.includes(b.name) && b.members.includes(a.name)) {
// Circular Reference: Skip because "a" AND "b" cannot be members of each other at the same time, so no re-ordering needed at the moment:
return 0;
} else if (a.members.includes(b.name) && !b.members.includes(a.name)) {
// "a" includes "b" as a member, so "a" should come after "b":
return 1;
} else if (!a.members.includes(b.name) && b.members.includes(a.name)) {
// "b" includes "a" as a member, so "b" should come after "a":
return -1;
} else if (!a.members.includes(b.name) && !b.members.includes(a.name)) {
// Neither "a" nor "b" include each other as a member, so no re-ordering needed at the moment:
return 0;
} else {
// OTHERWISE, use the secondary sort by "name", where it could not be sorted by "members":
return a.name.localeCompare(b.name);
}
});
console.log(example);
Приведенный выше код дает неверный результат :
- «Пример 1»
- «Пример 3»
- «Пример 2»
- «Пример 4»
- «Пример 5»
Правильное значение , предназначенное результат должен быть:
- «Пример 3»
- «Пример 4»
- «Пример 1»
- «Пример 2»
- "Пример 5"
Каков наилучший способ сортировки этого массива на основе критериев, которые я перечислил выше?