Reputation: 8975
I have following array that needs to be sorted with respect to search text 'John'.
{id: 1, firstName: 'User', lastName: 'John', nickName: 'Smith'},
{id: 2, firstName: 'Test', lastName: 'John', nickName: 'Andrew'},
{id: 3, firstName: 'Test', lastName: 'Zch', nickName: 'John'},
{id: 4, firstName: 'Test', lastName: 'Mason', nickName: 'John'},
{id: 5, firstName: 'John', lastName: 'Doe'},
];
Expected Output:
Array should be first sorted with nickName (with search text) then lastName(with search text). If nickName is not present then it should sorted with respect to firstName(with search text) with ASC sorting order. Note: It should consider search text word as 'John'
This sort resembles like Search with Sort in your mobile's contact app
[
// sort with nickName as higher relevance considering search text as John
{id: 4, firstName: 'Test', lastName: 'Mason', nickName: 'John'},
{id: 3, firstName: 'Test', lastName: 'Zch', nickName: 'John'},
// sort with lastName considering search text
{id: 2, firstName: 'Test', lastName: 'John', nickName: 'Andrew'},
{id: 1, firstName: 'User', lastName: 'John', nickName: 'Smith'},
// sort with firstName as nickName is null
{id: 5, firstName: 'John', lastName: 'Doe'},
];
I tried localeMethod
function sortByLocale(user1, user2) {
var sortByNickName = user1.nickName.toLowerCase().localeCompare(user2.nickName.toLowerCase());
var sortByLastName = user1.lastName.toLowerCase().localeCompare(user2.lastName.toLowerCase());
return sortByNickName || sortByLastName;
}
But the result is not considering search text while sorting. One approach, I can see is creating three different arrays and sort them and combined those sorted array Any helps would be appreciated.
Edit: Not considering the non-matched object with search text value
Upvotes: 1
Views: 410
Reputation: 386680
You could take two iterations for the wanted order
var data = [{ id: 1, firstName: 'User', lastName: 'John', nickName: 'Smith' },
{ id: 2, firstName: 'Test', lastName: 'John', nickName: 'Andrew' },
{ id: 3, firstName: 'Test', lastName: 'Zch', nickName: 'John' },
{ id: 4, firstName: 'Test', lastName: 'Mason', nickName: 'John' },
{ id: 5, firstName: 'John', lastName: 'Doe' }
],
search = 'john',
check = (s => (o, k) => (o[k] || '').toLowerCase() === search)(search),
keys = ['nickName', 'lastName', 'firstName'];
data.sort((a, b) => {
const
fns = [
k => d = check(b, k) - check(a, k),
k => d = (a[k] || '').localeCompare(b[k] || '')
];
let d = 0;
fns.some(fn => keys.some(fn));
return d;
});
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 3032
Just add first search by name
function checkSearch (value) {
return (value.nickName === 'John') * -3 ||
(value.lastName === 'John') * -2 ||
(value.firstName === 'John') * -1 ||
0
}
function sortByLocale(user1, user2) {
var sortBySearch = checkSearch(user1) - checkSearch(user2)
var sortByNickName = (user1.nickName || '').toLowerCase().localeCompare((user2.nickName || '').toLowerCase());
var sortByLastName = user1.lastName.toLowerCase().localeCompare(user2.lastName.toLowerCase());
return sortBySearch || sortByNickName || sortByLastName;
}
Upvotes: 1