Reputation: 27852
I have an array with objects that looks like this:
[{
id: 34,
users: [{
name: 'Lisa',
age: 23
}, {
name: 'Steven',
age: 24
}]
} ,{
id: 35,
users: [{
name: 'John',
age: 23,
}, {
name: 'Steven',
age: 24
}, {
name: 'Charlie',
age: 24
}]
}, {
id: 36,
users: [{
name: 'Lisa',
age: 23,
}, {
name: 'John',
age: 24
}, {
name: 'Homer',
age: 24
}, {
name: 'Charlie',
age: 24
}]
}, {
id: 37,
users: [{
name: 'Lisa',
age: 23
}, {
name: 'John',
age: 24
}]
}]
I want to order the array based on a couple of conditions (prioritized): First I want the objects that have users with name 'John' AND 'Lisa' and number of users is less than 3 Secondly I want the objects that have users with name 'John' AND 'Lisa' regardless of the number of participants Then the rest of the objects
So, the array that I put as an example, would become:
[{
id: 37,
users: [{
name: 'Lisa',
age: 23
}, {
name: 'John',
age: 24
}]
}, {
id: 36,
users: [{
name: 'Lisa',
age: 23
}, {
name: 'John',
age: 24
}, {
name: 'Homer',
age: 24
}, {
name: 'Charlie',
age: 24
}]
}, {
id: 34,
users: [{
name: 'Lisa',
age: 23
}, {
name: 'Steven',
age: 24
}]
}, {
id: 35,
users: [{
name: 'John',
age: 23
}, {
name: 'Steven',
age: 24
}, {
name: 'Charlie',
age: 24
}]
}]
I have this right now, which properly sorts based on the names AND number of participants. But if the number of participants doesn't match, then it doesn't care about the names to sort, which is wrong:
const names = ['John', 'Lisa']
unorderedLeagues.sort((a, b) => {
const aUserIncluded = every(names, priorityName =>
some(a.users, { name: priorityName }),
);
const bUserIncluded = every(names, priorityName =>
some(b.users, { name: priorityName }),
);
return (
(bUserIncluded && b.users.length <= 3) -
(aUserIncluded && a.users.length <= 3)
);
});
How should I modify this sorting to do the type of priority I described?
Upvotes: 1
Views: 3119
Reputation: 12309
Try some thing like this
yourObj.sort(function(curr,next){
return ((curr.users.filter(x=>x.name=='John'|| x.name=='Steven').length > 0) && curr.users.length < 3 )? 1 : 2;
})
var arrObj= [{
id: 34,
users: [{
name: 'Lisa',
age: 23
}, {
name: 'Steven',
age: 24
}]
} ,{
id: 35,
users: [{
name: 'John',
age: 23,
}, {
name: 'Steven',
age: 24
}, {
name: 'Charlie',
age: 24
}]
}, {
id: 36,
users: [{
name: 'Lisa',
age: 23,
}, {
name: 'John',
age: 24
}, {
name: 'Homer',
age: 24
}, {
name: 'Charlie',
age: 24
}]
}, {
id: 37,
users: [{
name: 'Lisa',
age: 23
}, {
name: 'John',
age: 24
}]
}];
arrObj.sort(function(curr,next){
return ((curr.users.filter(x=>x.name=='John'|| x.name=='Steven').length > 0) && curr.users.length < 3 )? 1 : 2;
});
console.log(arrObj);
Upvotes: 0
Reputation: 386604
You could use a boolean value for checking if the wanted names are in users
. Then take the length as well or not.
var array = [{ id: 34, users: [{ name: 'John', age: 23}, { name: 'Steven', age: 24}] }, { id: 35, users: [{ name: 'John', age: 23}, { name: 'Steven', age: 24}, { name: 'Charlie', age: 24}] }, { id: 36, users: [{ name: 'Lisa', age: 23}, { name: 'John', age: 24}, { name: 'Homer', age: 24}, { name: 'Charlie', age: 24}] }, { id: 37, users: [{ name: 'Lisa', age: 23}, { name: 'John', age: 24}] }],
find = ['John', 'Lisa'];
array.sort(function (a, b) {
var aAll = find.every(n => a.users.find(({ name }) => name === n)),
bAll = find.every(n => b.users.find(({ name }) => name === n));
return (bAll && b.users.length === 2) - (aAll && a.users.length === 2) || bAll - aAll;
});
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 2
Reputation: 7346
This method should do the job:
var unsorted = [{
id: 34,
users: [{
name: 'Lisa',
age: 23
},
{
name: 'Steven',
age: 24
}
]
},
{
id: 35,
users: [{
name: 'John',
age: 23
},
{
name: 'Steven',
age: 24
},
{
name: 'Charlie',
age: 24
}
]
},
{
id: 36,
users: [{
name: 'Lisa',
age: 23
},
{
name: 'John',
age: 24
},
{
name: 'Homer',
age: 24
},
{
name: 'Charlie',
age: 24
}
]
},
{
id: 37,
users: [{
name: 'Lisa',
age: 23
},
{
name: 'John',
age: 24
}
]
}
];
var sorted = unsorted.sort((a, b) => sortMethod(a, b));
console.log(sorted);
function sortMethod(a, b) {
var con1a = a.users.find(u => u.name == 'Lisa') && a.users.find(u => u.name == 'John');
var con1b = b.users.find(u => u.name == 'Lisa') && b.users.find(u => u.name == 'John');
if (con1a && !con1b) return -1;
if (!con1a && con1b) return 1;
return a.users.length - b.users.length;
}
Side note: I had to reformat the invalid JSON first, to get it successfully parsed.
Upvotes: 0