4

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"

2
  • 2
    Is it always a word, then a space, and then a number? Commented Dec 3, 2021 at 17:01
  • Yes but word can be more than one, but it always ends with number Commented Dec 3, 2021 at 17:03

2 Answers 2

8

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);

Sign up to request clarification or add additional context in comments.

4 Comments

it works perfect!
Nice answer! I would have done it with regex and do the logic myself, but this is much better. Nice to learn about collator and the numeric option
Great, I'm glad it works :)
twice faster than localeCompare. nice answer +1
2

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})))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.