Reputation: 664
I have the following array:
var objs = [
{ id: 'X82ns', name: 'james', presence: 'online' },
{ id: '8YSHJ', name: 'mary', presence: 'offline' },
{ id: '7XHSK', name: 'rene', presence: 'online' }
];
I want to sort the array so it returns a new array by 'presence': 'online' users displaying first before offline items.
So if sorted, it should return something like this:
var objs = [
{ id: 'X82ns', name: 'james', presence: 'online' },
{ id: '7XHSK', name: 'rene', presence: 'online' },
{ id: '8YSHJ', name: 'mary', presence: 'offline' }
];
Something like this:
const newArray = objs.sort((a, b) => {
if (a.presence === 'online') {
return 1;
} else if (b.presence === 'offline') {
return -1;
} else {
return 0;
}
})
return newArray;
}
What is the right way to get the expected result?
Upvotes: 2
Views: 142
Reputation: 8740
@Oj Obasi, try the below code.
It uses map() method defined on arrays.
var objs = [
{ id: 'X82ns', name: 'james', presence: 'online' },
{ id: '8YSHJ', name: 'mary', presence: 'offline' },
{ id: '7XHSK', name: 'rene', presence: 'online' }
];
/* Pretty printing objs array*/
console.log(JSON.stringify(objs, null, 4)) // Before modification (sorting)
/*
[
{
"id": "X82ns",
"name": "james",
"presence": "online"
},
{
"id": "8YSHJ",
"name": "mary",
"presence": "offline"
},
{
"id": "7XHSK",
"name": "rene",
"presence": "online"
}
]
*/
objs.map((item, index) => {
if(item.presence === 'online') { // online, add to front then remove this item from its current position
objs.splice(0, 0, item) // add at front
} else { // offline, push at end then remove this item from its current position
objs.splice(objs.length, 1, item) // push at end
}
objs.splice(index, 1) // remove
})
/* Pretty printing objs array */
console.log(JSON.stringify(objs, null, 4)) // After modification (sorting)
/*
[
{
"id": "X82ns",
"name": "james",
"presence": "online"
},
{
"id": "7XHSK",
"name": "rene",
"presence": "online"
},
{
"id": "8YSHJ",
"name": "mary",
"presence": "offline"
}
]
*/
Upvotes: 0
Reputation: 6106
Try this:
const newArray = objs.sort((a, b) => {
if (a.presence === 'online' && b.presence === 'offline') {
return 1;
} else if (b.presence === 'online' && a.presence === 'offline') {
return -1;
} else {
return 0;
}
})
return newArray;
}
Upvotes: 1
Reputation: 23
Try This:
var objs = [
{ id: 'X82ns', name: 'james', presence: 'online' },
{ id: '8YSHJ', name: 'mary', presence: 'offline' },
{ id: '7XHSK', name: 'rene', presence: 'online' }
];
var statusOrder = ["online", "offline"];
objs = objs.sort(function(a, b) {
return statusOrder.indexOf(a.presence) - statusOrder.indexOf(b.presence);
});
Even shorter with ECMAScript6:
objs = objs.sort((a, b) => statusOrder.indexOf(a.presence) - statusOrder.indexOf(b.presence));
Answer taken from Faly's answer to another post.
Upvotes: 0
Reputation: 752
You need to actually compare the items, and if they are now the same, then check for presence
var objs = [
{ id: 'X82ns', name: 'james', presence: 'online' },
{ id: '8YSHJ', name: 'mary', presence: 'offline' },
{ id: '7XHSK', name: 'rene', presence: 'online' }
];
const newArray = objs.sort((a, b) => {
if (a.presence !== b.presence) {
return a.presence === "online" ? -1 : 1;
}
return 0;
});
console.log(newArray);
Upvotes: 1
Reputation: 30739
Use the >
sign to get online
first and offline
at the end. You can also create a separate function sortFn
so this logic can be reused for multiple arrays.
var objs = [
{ id: 'X82ns', name: 'james', presence: 'online' },
{ id: '8YSHJ', name: 'mary', presence: 'offline' },
{ id: '7XHSK', name: 'rene', presence: 'online' }
];
function sortFn(a, b){
return b.presence > a.presence;
}
objs.sort(sortFn);
console.log(objs);
Upvotes: 1
Reputation: 386654
You could take an object with the order as values and sort by it. This allowes to use a default value for unknow values.
var array = [{ id: 'X82ns', name: 'james', presence: 'online' }, { id: '8YSHJ', name: 'mary', presence: 'offline' }, { id: '7XHSK', name: 'rene', presence: 'online' }],
order = { online: 1, offline: 2, default: Infinity };
array.sort((a, b) => (order[a.presence] || order.default) - (order[b.presence] || order.default));
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 12874
let objArr = [
{ id: 'X82ns', name: 'james', presence: 'online' },
{ id: '8YSHJ', name: 'mary', presence: 'offline' },
{ id: '7XHSK', name: 'rene', presence: 'online' }
];
let onlineArr = objArr.filter(x=>x.presence === 'online')
let offlineArr = objArr.filter(x=>x.presence === 'offline')
console.log([...onlineArr, ...offlineArr])
In terms of readability, you can split them into two array and using array destructuring to join them at last
Upvotes: 1
Reputation: 12880
You could simply compare the String with >
, =
and <
let objs = [
{ id: 'X82ns', name: 'james', presence: 'online' },
{ id: '8YSHJ', name: 'mary', presence: 'offline' },
{ id: '7XHSK', name: 'rene', presence: 'online' }
];
let res = objs.sort((a,b) => a.presence > b.presence ? -1 : a.presence == b.presence ? 0 : 1);
console.log(res);
Upvotes: 1
Reputation: 5488
Use sort
function with condition of a.presence < b.presence because of online
is bigger than offline
(f
and n
)
var objs = [
{ id: 'X82ns', name: 'james', presence: 'online' },
{ id: '8YSHJ', name: 'mary', presence: 'offline' },
{ id: '7XHSK', name: 'rene', presence: 'online' }
];
objs.sort(function(a, b) {
return a.presence < b.presence;
});
console.log(objs);
Upvotes: 1
Reputation: 48367
You can use localeCompare
method.
var objs = [ { id: 'X82ns', name: 'james', presence: 'online' }, { id: '8YSHJ', name: 'mary', presence: 'offline' }, { id: '7XHSK', name: 'rene', presence: 'online' } ];
objs.sort((a,b) => b.presence.localeCompare(a.presence));
console.log(objs);
Don't forget that the sort()
method sorts the elements of an array in place so you do not need to use const newArray = objs.sort...
.
Upvotes: 6