0

I have a string array with values in the format "dd MMMM":

var myArray = ['13 October','13 November','13 May','13 August','13 November','13 February','13 May',
'13 August','13 November','13 February','13 May','13 August','13 November','13 February','13 May',
'13 August','13 November','13 February','13 May','13 August','13 November','14 November']

I need remove duplicates whilst maintaining date order.

I started off with:

function myFunction(array) {
    array.sort();
    newArray = [array[0]];
    for (i = 1; i < array.length; i++) {
        if (array[i] != array[i-1]) {
            newArray.push(array[i]);
        }
    }
    return newArray
}; 

That results in an array which is no longer in date order, so as a hack I then looped through the string array, appended " 9999" to the end of each value and then parsed it as a date. I sorted the new array, before formatting each value as "dd MMMM" to give me the final output:

['13 February','13 May','13 August','13 October','13 November','14 November']

Whilst it works, it is some terrible code. Any advice on how to remove duplicates from the initial array and sort it by strings which have "dd MMMM" and no "yyyy"?

/Edit: Apologies, I should have mentioned that this JavaScript is being in a third party application and it doesn't support many of the common methods - Set, indexOf, =>, sortBy etc.

1
  • Use a comparison function that converts the strings to dates and compares them. Commented Aug 17, 2023 at 21:23

1 Answer 1

3

Use Set - the fastest way to get unique values from an array and sort the result. I think there's nothing wrong to append a year string to get it parsed as a date:

var myArray = ['13 October','13 November','13 May','13 August','13 November','13 February','13 May',
'13 August','13 November','13 February','13 May','13 August','13 November','13 February','13 May',
'13 August','13 November','13 February','13 May','13 August','13 November','14 November']


const result = [...new Set(myArray)].sort((a, b) => new Date(a + ' 2001') - new Date(b + ' 2001'));

console.log(result);

About avoiding adding the year string - you can parse and sort the dates manually:

var myArray = ['13 October','13 November','13 May','13 August','13 November','13 February','13 May',
'13 August','13 November','13 February','13 May','13 August','13 November','13 February','13 May',
'13 August','13 November','13 February','13 May','13 August','13 November','14 November']

const format = new Intl.DateTimeFormat('en', {month: 'long'}).format;
const date = new Date('2023-01-01T00:00Z');
const months = Array.from({length: 12}, (_, m) => format(date.setMonth(m)));

const result = [...new Set(myArray)].sort((a, b) => {
  const [dateA, monthA] = a.split(' ');
  const [dateB, monthB] = b.split(' ');
  if(monthA === monthB){
    return dateA - dateB;
  }
  return months.indexOf(monthA) - months.indexOf(monthB);
});
console.log(result);

The manual parsing seems faster:

enter image description here

<script benchmark data-count="100000">

var myArray = ['13 October','13 November','13 May','13 August','13 November','13 February','13 May',
'13 August','13 November','13 February','13 May','13 August','13 November','13 February','13 May',
'13 August','13 November','13 February','13 May','13 August','13 November','14 November']

const dates = [...new Set(myArray)];

// @benchmark manual parsing

const format = new Intl.DateTimeFormat('en', {month: 'long'}).format;
const date = new Date('2023-01-01T00:00Z');
const months = Array.from({length: 12}, (_, m) => format(date.setMonth(m)));

// @run
dates.toSorted((a, b) => {
  const [dateA, monthA] = a.split(' ');
  const [dateB, monthB] = b.split(' ');
  if(monthA === monthB){
    return dateA - dateB;
  }
  return months.indexOf(monthA) - months.indexOf(monthB);
});

// @benchmark Date parsing
dates.toSorted((a, b) => new Date(a + ' 2001') - new Date(b + ' 2001'));


</script>
<script src="https://cdn.jsdelivr.net/gh/silentmantra/benchmark/loader.js"></script>

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

1 Comment

Apologies, I should have mentioned that this JavaScript is being in a third party application and it doesn't support many of the common methods - Set, indexOf, =>, sortBy etc.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.