skip to Main Content

Given an array of countries with offices opened, how do I sort the array in order from the earliest date recorded to the latest date recorded?
The original array is

countriesList = [
 { country: 'USA',
 officeOpened: [ {date: '2016-04-01', city: 'Denver'}],
 officeClosed: [ {date: '2016-10-01', city: 'NY'}]
 },
 { country: 'UK',
 officeOpened: [{date: '2023-05-01', city: 'London'}],
 officeClosed: []
 },
 { country: 'China',
 officeOpened: [{date: '2015-01-01', city: 'Shanghai'}],
 officeClosed: []
 },
 { country: 'No-office',
 officeOpened: [],
 officeClosed: []
 },
 { country: 'Many-offices',
 officeOpened: [{date: '2023-04-01', city: 'A'} , {date: '2023-06-01', city: 'B'}],
 officeClosed: []
 }
]

Expected output:

countriesList = [
 { country: 'China',
 officeOpened: [{date: '2015-01-01', city: 'Shanghai'}]
 },
 { country: 'USA',
 officeOpened: [ {date: '2016-04-01', city: 'Denver'}],
 officeClosed: [ {date: '2016-10-01', city: 'NY'}]
 },
 { country: 'Many-offices',
 officeOpened: [{date: '2023-04-01', city: 'A'} , {date: '2023-06-01', city: 'B'}],
 officeOpened: []
 },
 { country: 'UK',
 officeOpened: [{date: '2023-05-01', city: 'London'}]
 },
  { country: 'No-office',
 officeOpened: [],
 officeOpened: []
 }
]

So I want to sort the country object in this array. Notice how the earliest date record was in China, so the whole China object is sorted to the first place, then comes the second earliest date recorded in the USA, the UK. How do I do this?
I’ve seen some similar question, but not exactly with this type of data structure.

Edit: if it’s relevant, officeOpened/Closed can also be empty, in which case, it can either be first or last in the array. And as one of the answer points out, we only need to care about and sort base on the first office opened in a country (the first object in officeOpened/Closed array because these arrays are sorted beforehand.)

3

Answers


  1. If we can assume that 1. officeOpened will always be before officeClosed, and 2. each officeOpened will always have an element in the array, and 3. There will only be one element in the officeOpened array or we only care about the first element, then we can do:

    countriesList = [
     { country: 'USA',
     officeOpened: [ {date: '2016-04-01', city: 'Denver'}],
     officeClosed: [ {date: '2016-10-01', city: 'NY'}]
     },
     { country: 'UK',
     officeOpened: [{date: '2023-05-01', city: 'London'}]
     },
     { country: 'China',
     officeOpened: [{date: '2015-01-01', city: 'Shanghai'}]
     }
    ]
    
    countriesList.sort((a, b) => a.officeOpened[0].date.localeCompare(b.officeOpened[0].date));
    
    console.log(countriesList);
    Login or Signup to reply.
  2. You could take the date and sort by string.

    const
        countriesList = [{ country: 'USA', officeOpened: [{ date: '2016-04-01', city: 'Denver' }], officeClosed: [{ date: '2016-10-01', city: 'NY' }] }, { country: 'UK', officeOpened: [{ date: '2023-05-01', city: 'London' }] }, { country: 'China', officeOpened: [{ date: '2015-01-01', city: 'Shanghai' }] }];
        
    countriesList.sort(({ officeOpened: [a] }, { officeOpened: [b] }) =>
        a.date.localeCompare(b.date)
    );
    
    console.log(countriesList);
    .as-console-wrapper { max-height: 100% !important; top: 0; }
    Login or Signup to reply.
  3. As officeOpened is an array, I assume this array can have multiple entries for each country. If yes, the following searches the earliest date for each countries and then sorts by this date.

    var countriesList = [
      { 
        country: 'USA',
        officeOpened: [ {date: '2016-04-01', city: 'Denver'}],
        officeClosed: [ {date: '2016-10-01', city: 'NY'}]
      },
      { 
        country: 'UK',
        officeOpened: [{date: '2023-05-01', city: 'London'}],
        officeClosed: []
      },
      { 
        country: 'China',
        officeOpened: [{date: '2015-01-01', city: 'Shanghai'}],
        officeClosed: []
      },
      { 
        country: 'No-office',
        officeOpened: [],
        officeOpened: []
      },
      { 
        country: 'Many-offices',
        officeOpened: [{date: '2023-04-01', city: 'A'} , {date: '2023-06-01', city: 'B'}],
        officeClosed: []
      }
    ]
    
    function earliestDate(country) {
      let props = ["officeOpened", "officeClosed"];
      let earliest = props
        .map(p => country[p]?.map(x => x.date).sort()[0])  //find the minium date in each of the arrays
        .filter(x  => !!x)  //filter out empty values (in case an array is empty or does not exist at all)
        .sort()[0];  //find the minimum of the remaining values
      return earliest ?? "9999"
    }
    
    var sorted = countriesList.slice().sort((a,b) => earliestDate(a).localeCompare(earliestDate(b)));
    
    console.log(sorted)

    The earliestDate function searches for the earliest date in all arrays defined in the props array. If none exists, "9999" is returned, so that country is moved to the end of the list.

    Of course this implementation is not the fastest one, as it recalculates the earliestDate in every comparison of the sort. Also using sort to find the minimum of an array is inefficient. But you should get the basic idea on how to sort your values.

    A better implementation would call earliestDate once for every element in the array and reuse this value. Also finding the minium date via sort is not optimal, a faster way would just be a simple iteration. But I leave that as exercise …

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search