Reputation: 5157
Given the following array of objects:
const arr = [
{
"unit": "Room 2",
"name": "House A"
},
{
"unit": "Room 1",
"name": "House A"
},
{
"unit": "Main House",
"name": "House A"
},
{
"unit": "Room 3",
"name": "House B"
},
{
"unit": "Room 1",
"name": "House B"
},
{
"unit": "Room 2",
"name": "House B"
},
{
"unit": "Main House",
"name": "House B"
},
]
I would like to sort it like the below example:
[
{ unit: 'Main House', name: 'House A' },
{ unit: 'Room 1', name: 'House A' },
{ unit: 'Room 2', name: 'House A' },
{ unit: 'Main House', name: 'House B' },
{ unit: 'Room 1', name: 'House B' },
{ unit: 'Room 2', name: 'House B' },
{ unit: 'Room 3', name: 'House B' }
]
Where I can say move the objects where unit === 'Main House'
to the top of the other values that share the same name
I try the below to no avail
const result = arr.sort((c1, c2) => (c1.unit === 'Main House' || c2.unit === 'Main House') ? 1 : -1)
Upvotes: 1
Views: 45
Reputation: 28980
Sort by name
first and by unit
second with an exception for "Main House"
to go to the top. String#localeCompare
makes sorting comparison a lot easier:
const arr = [
{ "unit": "Room 2" , "name": "House A" },
{ "unit": "Room 1" , "name": "House A" },
{ "unit": "Main House", "name": "House A" },
{ "unit": "Room 3" , "name": "House B" },
{ "unit": "Room 1" , "name": "House B" },
{ "unit": "Room 2" , "name": "House B" },
{ "unit": "Main House", "name": "House B" },
];
arr.sort((a, b) => {
const nameOrder = a.name.localeCompare(b.name);
if (nameOrder !== 0)
return nameOrder;
if(a.unit === "Main House")
return -1;
if (b.unit === "Main House")
return 1;
return a.unit.localeCompare(b.unit);
});
console.log(arr)
Which can be shortened with some (ab)use of logical operators and type coercion:
const arr = [{ "unit": "Room 2", "name": "House A" }, { "unit": "Room 1", "name": "House A" }, { "unit": "Main House", "name": "House A" },{ "unit": "Room 3", "name": "House B" },{ "unit": "Room 1", "name": "House B" },{ "unit": "Room 2", "name": "House B" },{ "unit": "Main House", "name": "House B" },];
arr.sort((a, b) =>
a.name.localeCompare(b.name) ||
((b.unit === "Main House") - (a.unit === "Main House")) ||
a.unit.localeCompare(b.unit)
);
console.log(arr);
Upvotes: 1
Reputation: 89214
You can check the criteria in order like so:
const arr=[{unit:"Room 2",name:"House A"},{unit:"Room 1",name:"House A"},{unit:"Main House",name:"House A"},{unit:"Room 3",name:"House B"},{unit:"Room 1",name:"House B"},{unit:"Room 2",name:"House B"},{unit:"Main House",name:"House B"}];
arr.sort((a, b) => a.name !== b.name ? a.name.localeCompare(b.name) :
a.unit === b.unit ? 0 :
a.unit === 'Main House' ? -1 :
b.unit === 'Main House' ? 1 : a.unit.localeCompare(b.unit))
console.log(arr);
Upvotes: 3