#javascript #sorting
Вопрос:
Я хочу сортировать участников на основе ключа groups
, который представляет собой массив групп (функция, подобная тегам). Я хочу отсортировать по предопределенному sortOrder
порядку, а затем по тому, верно ли значение main_contact, если существует несколько участников для одной и той же группы. Но я действительно застрял в том, как проверить, есть ли groups.name существует, а затем эффективно сортирует их по заданному порядку.
const attendees = [
{
name: "Peter",
groups: [{ name: "agency", main_contact: false, stand_in_contact: true }],
},
{
name: "Alex",
groups: [{ name: "agency", main_contact: true, stand_in_contact: false }],
},
{
name: "Nina",
groups: [
{ name: "production", main_contact: true, stand_in_contact: false },
],
},
{
name: "Christina",
groups: [
{ name: "client", main_contact: true, stand_in_contact: false },
{ name: "crew", main_contact: false, stand_in_contact: false },
],
},
];
const sortAttendees = (attendees) => {
const sortOrder = ["agency", "client", "production", "crew"];
// return sortOrder.indexOf(a.type) - sortOrder.indexOf(b.type);
if (!attendees || attendees.length == 0) return [];
return attendees.sort((a, b) => {
if (a.groups.some((group) => group.name === "agency")) {
return -1;
}
if (a.groups.some((group) => group.name === "client")) {
return 1;
}
if (a.groups.some((group) => group.name === "production")) {
return 1;
}
return 1;
});
};
Результат
const attendees = [
{
name: "Alex",
groups: [{ name: "agency", main_contact: true, stand_in_contact: false }],
},
{
name: "Peter",
groups: [{ name: "agency", main_contact: false, stand_in_contact: true }],
},
{
name: "Christina",
groups: [
{ name: "client", main_contact: true, stand_in_contact: false },
{ name: "crew", main_contact: false, stand_in_contact: false },
],
},
{
name: "Nina",
groups: [
{ name: "production", main_contact: true, stand_in_contact: false },
],
},
];
Ответ №1:
Похоже, сначала нужно отсортировать группы, а затем вы сможете сортировать участников.
const attendees = [
{
name: "Peter",
groups: [{ name: "agency", main_contact: false, stand_in_contact: true }],
},
{
name: "Alex",
groups: [{ name: "agency", main_contact: true, stand_in_contact: false }],
},
{
name: "Nina",
groups: [
{ name: "production", main_contact: true, stand_in_contact: false },
],
},
{
name: "Christina",
groups: [
{ name: "client", main_contact: true, stand_in_contact: false },
{ name: "crew", main_contact: false, stand_in_contact: false },
],
},
];
const sortOrder = ["agency", "client", "production", "crew"];
const sortAttendees = (attendees, sortOrder) => {
if ([attendees, sortOrder].some(a => !(a instanceof Array))) return;
// first, sort the groups:
attendees.forEach(attendee => attendee.groups.sort((a, b) => sortOrder.indexOf(a.name) - sortOrder.indexOf(b.name) || b.main_contact - a.main_contact));
// now sort attendees:
attendees.sort((a, b) => {
const l = Math.min(a.groups.length, b.groups.length);
for (let i = 0; i < l; i) {
const r = sortOrder.indexOf(a.groups[i].name) - sortOrder.indexOf(b.groups[i].name) || b.groups[i].main_contact - a.groups[i].main_contact;
if (r) return r;
}
return 0;
});
};
sortAttendees(attendees, sortOrder);
console.log( attendees )
.as-console-wrapper {top:0; max-height: 100% !important}
Ответ №2:
В своем решении я даю каждому участнику значение ранга, основанное на его членстве в группе с наивысшим рейтингом и статусе main_contact в этой группе.
const attendees = [
{
name: "Peter",
groups: [{ name: "agency", main_contact: false, stand_in_contact: true }],
},
{
name: "Alex",
groups: [{ name: "agency", main_contact: true, stand_in_contact: false }],
},
{
name: "Nina",
groups: [
{ name: "production", main_contact: true, stand_in_contact: false },
],
},
{
name: "Christina",
groups: [
{ name: "client", main_contact: true, stand_in_contact: false },
{ name: "crew", main_contact: false, stand_in_contact: false },
],
},
];
const sortAttendees = (attendees) => {
const sortOrder = ["agency", "client", "production", "crew"];
const rank = attendee => attendee.groups
.map(group => sortOrder.indexOf(group.name)*2 1 - group.main_contact)
.sort()
[0];
if (!attendees || attendees.length == 0) return [];
return attendees.sort((a, b) => rank(a)-rank(b));
};
console.log(sortAttendees(attendees));
.as-console-wrapper {top:0; max-height: 100% !important}