Reputation: 101
I am super stuck with sorting my array of objects.
const users = useMemo(() => [userDetails, ...otherParticipants]
.sort((a, b) => b.isTyping - a.isTyping)
.sort((a, b) => b.liveDetails.status - a.liveDetails.status)
.sort((a, b) => b.hasRaisedHand - a.hasRaisedHand)
.sort((a, b) => b.isOnline - a.isOnline)
, [userDetails, otherParticipants])
I tried chaining sorts and it worked a bit. Then I tried conditional, but nothing seemed to work with all that I needed to sort. I would really appreciate some guidance. Sorry for the long post...
[
{
isOnline: true,
hasRaisedHand: false,
isTyping: false,
liveDetails: {
status: 'pending',
camera: false,
mic: false,
},
},
{
isOnline: true,
hasRaisedHand: false,
isTyping: false,
liveDetails: {
status: 'active',
camera: false,
mic: false,
},
},
{
isOnline: false,
hasRaisedHand: false,
isTyping: false,
liveDetails: {
status: 'disabled',
camera: false,
mic: false,
},
},
{
isOnline: true,
hasRaisedHand: false,
isTyping: true,
liveDetails: {
status: 'disabled',
camera: false,
mic: false,
},
},
{
isOnline: true,
hasRaisedHand: true,
isTyping: false,
liveDetails: {
status: 'disabled',
camera: false,
mic: false,
},
},
]
This is the order I need the objects sorted into:
isTyping: true
status: 'active'
status: 'pending'
hasRaisedHand: true
isOnline: true
isOnline: false
example: an object that has the key isTyping: true
should be in front of the object that has a status: 'pending'
.
example 2: if an object has status: 'pending'
but also has isTyping: true
, it should be in the front of the array.
this is the order the objects need to sort into, but I cant seem to get it to work at all.
This would be the order I need:
[
{
isOnline: true,
hasRaisedHand: false,
**isTyping: true,**
liveDetails: {
status: 'disabled',
camera: false,
mic: false,
},
},
{
isOnline: true,
hasRaisedHand: false,
isTyping: false,
liveDetails: {
**status: 'active',**
camera: false,
mic: false,
},
},
{
isOnline: true,
hasRaisedHand: false,
isTyping: false,
liveDetails: {
**status: 'pending',**
camera: false,
mic: false,
},
},
{
isOnline: true,
**hasRaisedHand: true**,
isTyping: false,
liveDetails: {
status: 'disabled',
camera: false,
mic: false,
},
},
{
**isOnline: true,**
hasRaisedHand: false,
isTyping: false,
liveDetails: {
status: 'disabled',
camera: false,
mic: false,
},
},
{
**isOnline: false,**
hasRaisedHand: false,
isTyping: false,
liveDetails: {
status: 'disabled',
camera: false,
mic: false,
},
},
]
Upvotes: 1
Views: 77
Reputation: 1448
Try this code where we sort the data based on a sorting score of elements as per your requirements. Notice that they have a priority based sore i.e., higher the sorting priority criteria, higher the score. The gap between each sorting criteria is kept far apart so that conditions don't overlap. If conditions increase so will we change the score type increments. Check this:
function getScore(a) {
var n = a.isTyping ? 30 : 0;
n += a.liveDetails.status == 'active' ? 15 : 0;
n += a.liveDetails.status == 'pending' ? 14 : 0;
n += a.hasRaisedHand ? 8 : 0;
n += a.isOnline ? 2 : 0;
return n;
}
var results = data.sort((a, b) => getScore(a) < getScore(b));
console.log(results);
Upvotes: 1
Reputation: 386680
You could chain the conditions inside of sort
by using an object for sorting various states.
const
data = [{ isOnline: true, hasRaisedHand: false, isTyping: false, liveDetails: { status: 'pending', camera: false, mic: false } }, { isOnline: true, hasRaisedHand: false, isTyping: false, liveDetails: { status: 'active', camera: false, mic: false } }, { isOnline: false, hasRaisedHand: false, isTyping: false, liveDetails: { status: 'disabled', camera: false, mic: false } }, { isOnline: true, hasRaisedHand: false, isTyping: true, liveDetails: { status: 'disabled', camera: false, mic: false } }, { isOnline: true, hasRaisedHand: true, isTyping: false, liveDetails: { status: 'disabled', camera: false, mic: false } }],
status = { active: 1, pending: 2, disabled: 3 };
data.sort((a, b) =>
b.isTyping - a.isTyping ||
status[a.liveDetails.status] - status[b.liveDetails.status] ||
b.hasRaisedHand - a.hasRaisedHand ||
b.isOnline - a.isOnline
);
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 2