There is list of object contains data like below:
[
{name: 'Foo 1'},
{name: 'Foo 14'},
..
{name: 'Foo 2'},
{name: 'Bar 1'},
{name: 'Bar 15'},
...
{name: 'Bar 2'},
]
I need to sort this as
[
{name: 'Bar 1'},
{name: 'Bar 2'},
...
{name: 'Bar 15'},
{name: 'Foo 1'},
{name: 'Foo 1'},
...
{name: 'Foo 12'},
]
With classic character sorting 'Foo 14' gets ahead of 'Foo 2' so I need to sort by letter and numbers.
value pattern: There might be multiple words but always ends with number like "word word .. number"
CodePudding user response:
You could use Collator#compare
for this. The compare()
method compares two strings according to the sort order of the Intl.Collator
object. Just make sure you pass an options object where you set numeric
to true
:
const collator = new Intl.Collator("en", {
numeric: true,
sensitivity: "base",
});
const arr = [
{ name: "Foo 1" },
{ name: "Baz 21" },
{ name: "Foo 14" },
{ name: "Foo 2" },
{ name: "Bar 1" },
{ name: "Baz 10" },
{ name: "Bar 15" },
{ name: "Bar 2" },
{ name: "Baz 1" },
{ name: "Baz 2" },
];
const sorted = arr.sort((a, b) => collator.compare(a.name, b.name));
console.log(sorted);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
It appears that Intl.Collator
is almost twice as fast as localeCompare
. So, I would use @ZsoltMeszaros answer.
Using String.prototype.localeCompare()
:
const arr = [
{ name: "Foo 1" },
{ name: "Baz 21" },
{ name: "Foo 14" },
{ name: "Foo 2" },
{ name: "Bar 1" },
{ name: "Baz 10" },
{ name: "Bar 15" },
{ name: "Bar 2" },
{ name: "Baz 1" },
{ name: "Baz 2" },
];
console.log(arr.sort((a,b)=>a.name.localeCompare(b.name,'en',{numeric : true})))
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>