Reputation: 314
I have a json array, which I need to short first based on some search text, and then alphabetically. so basically in below array if I search for "beau" everything starting with beau should be kept on top(sorted alphabetically), and the remaining results will be sorted also alphabetically(even if we have that search text somewhere in the middle of the text) and should start right after the ones
Need solution in Javascript
Array :
[
{
"value": "1",
"text": "BEAUMONT Habitation 54"
},
{
"value": "2",
"text": "BEAUMONT Place de Renival"
},
{
"value": "3",
"text": "BEAUMONT Rue des Tiennes"
},
{
"value": "4",
"text": "BEAUMONT Rue Grand Chemin"
},
{
"value": "5",
"text": "BRUYERES Chênes"
},
{
"value": "6",
"text": "CEROUX Cabine"
},
{
"value": "7",
"text": "CEROUX Chapelle aux Sabots"
},
{
"value": "8",
"text": "CEROUX Place Communale"
},
{
"value": "9",
"text": "CEROUX Quatre Bras"
},
{
"value": "10",
"text": "Station Jambeaux"
},
{
"value": "11",
"text": "Reseau Street"
},
{
"value": "12",
"text": "beaux street"
}
]
EDIT
This is fine, but in another case where I have this data transformed in something like this, this sort is not working
{
"item":{
"value":"1558",
"text":"BEAUMONT Habitation 54"
},
"refIndex":0,
"matches":[
{
"indices":[
[
0,
1
]
],
"value":"BEAUMONT Habitation 54",
"key":"text"
}
],
"score":0.018533147937493524
},
{
"item":{
"value":"1560",
"text":"BEAUMONT Place de Renival"
},
"refIndex":3,
"matches":[
{
"indices":[
[
0,
1
]
],
"value":"BEAUMONT Place de Renival",
"key":"text"
}
],
"score":0.03162277660168379
}
]
to make it work I made some changes to the code, but it doesn't seems to work.
function sortByInput(data, input = null) {
if (!input) {
return data.sort((a, b) => a.item.text.localeCompare(b.item.text));
}
return data.sort((a, b) => {
const regex = new RegExp(`(^${input})`, "i");
const aMatch = regex.test(a.item.text);
const bMatch = regex.test(b.item.text);
if (aMatch || bMatch) return -aMatch + bMatch;
return a.item.text.localeCompare(b.item.text);
});
}
Upvotes: 0
Views: 645
Reputation: 144
The most basic solution is to use the default Javascript Array.sort method and pass your own compare function.
In the example below I check if there is any input
and depending on that I sort just alphabetically, or I sort by input
(by checking with the Regular Expression if the element starts with input
) and then sort alphabetically.
const data = [
{ value: "1", text: "BEAUMONT Habitation 54" },
{ value: "2", text: "BEAUMONT Place de Renival" },
{ value: "3", text: "BEAUMONT Rue des Tiennes" },
{ value: "4", text: "BEAUMONT Rue Grand Chemin" },
{ value: "5", text: "BRUYERES Chênes" },
{ value: "6", text: "CEROUX Cabine" },
{ value: "7", text: "CEROUX Chapelle aux Sabots" },
{ value: "8", text: "CEROUX Place Communale" },
{ value: "9", text: "CEROUX Quatre Bras" },
{ value: "10", text: "Station Jambeaux" },
{ value: "11", text: "Reseau Street" },
{ value: "12", text: "beaux street" }
];
function sortByInput(data, input = null) {
if (!input) {
return data.sort((a, b) => a.text.localeCompare(b.text));
}
return data.sort((a, b) => {
const regex = new RegExp(`(^${input})`, "i");
const aMatch = regex.test(a.text);
const bMatch = regex.test(b.text);
if (aMatch || bMatch) return -aMatch + bMatch;
return a.text.localeCompare(b.text);
});
}
console.log(sortByInput([...data], "ceroux"));
here is an updated version
with a third parameter compareValue
which specifies the value that it sorts by (I made it default to "item.text"
which matches your example)
I also added the function getProp
to dynamically get the props of data with the String compareValue
function sortByInput(data, input = null, compareValue = "item.text") {
const getProp = (object, path) =>
path.split(".").reduce((o, p) => o[p], object);
if (!input) {
return data.sort((a, b) =>
getProp(a, compareValue).localeCompare(getProp(b, compareValue))
);
}
return data.sort((a, b) => {
const regex = new RegExp(`(^${input})`, "i");
const aMatch = regex.test(getProp(a, compareValue));
const bMatch = regex.test(getProp(b, compareValue));
if (aMatch || bMatch) return -aMatch + bMatch;
return getProp(a, compareValue).localeCompare(getProp(b, compareValue));
});
}
Upvotes: 1