1

I have the following json data:

data = [
  {
    stateCode: 'CH',
    startDate: new Date('06/12/2020 08:00'),
    startDateWithDelay: new Date('06/12/2020 08:00'),
  },
  {
    stateCode: 'LA',
    startDate: new Date('06/12/2020 08:00'),
    startDateWithDelay: new Date('06/12/2020 08:30'),
  },
  {
    stateCode: 'NY',
    startDate: new Date('06/12/2020 06:00'),
    startDateWithDelay: new Date('06/12/2020 06:00')
  }
]

The data should be sorted by startDate by default. But if the startDate for 2 records is same then it should be sorted by stateDateWithDelay property. In the above example, startDate for first 2 records is same. So, in that case it should be sorted based on startDateWithDelay property.

After sorting the result should display the following states based on the 2 dates:

New York NY Chicago CH Los Angeles LA

I am using the following code to sort based on the startDate

import { sortBy } from 'lodash-es'
data = data.sortBy(data, (obj) => obj.startDate);

How do the accomplish sorting by the startDateWithDelay property when startDate is same for first 2 records.

Thanks

4 Answers 4

1

You can sort based on two parameters using a custom sort function passed to Array.prototype.sort

const data = [
  {
    stateCode: 'CH',
    startDate: new Date('06/12/2020 08:00'),
    startDateWithDelay: new Date('06/12/2020 08:00'),
  },
  {
    stateCode: 'LA',
    startDate: new Date('06/12/2020 08:00'),
    startDateWithDelay: new Date('06/12/2020 08:30'),
  },
  {
    stateCode: 'NY',
    startDate: new Date('06/12/2020 06:00'),
    startDateWithDelay: new Date('06/12/2020 06:00')
  }
]

const sorted = data.sort((a, b) => {
  const startDateComparison = a.startDate - b.startDate
  if (startDateComparison !== 0) return startDateComparison
  return a.startDateWithDelay - b.startDateWithDelay
})

console.log(sorted)

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

1 Comment

can we not make use of lodash ? this logic is inside my react application.
0

You can do something like this

data = [
  {
    stateCode: 'CH',
    startDate: new Date('06/12/2020 08:00'),
    startDateWithDelay: new Date('06/12/2020 08:00'),
  },
  {
    stateCode: 'LA',
    startDate: new Date('06/12/2020 08:00'),
    startDateWithDelay: new Date('06/12/2020 08:30'),
  },
  {
    stateCode: 'NY',
    startDate: new Date('06/12/2020 06:00'),
    startDateWithDelay: new Date('06/12/2020 06:00')
  }
];

data.sort((a,b)=>{
 if(a.startDate.getTime() < b.startDate.getTime()){
  return -1
 }else if(a.startDate.getTime() < b.startDate.getTime()){
  return 1
 }else{
  return a.startDateWithDelay.getTime() - b.startDateWithDelay.getTime()
 }
});

console.log(data)

1 Comment

Or data.sort((a, b) => (a.startDate - b.startDate) || (a.startWithDelay - b.startWithDelay)). ;-)
0

The best approach is to use Array.prototype.sort as, Array.prototype.sort function gives us the flexibility to override the sorting behavior of an array for any type of array data, and can be used for custom sorting orders over custom properties. Look at the last example that I have given.

const data = [
  {
    stateCode: "CH",
    startDate: new Date("06/12/2020 08:00"),
    startDateWithDelay: new Date("06/12/2020 08:00"),
  },
  {
    stateCode: "LA",
    startDate: new Date("06/12/2020 08:00"),
    startDateWithDelay: new Date("06/12/2020 08:30"),
  },
  {
    stateCode: "NY",
    startDate: new Date("06/12/2020 06:00"),
    startDateWithDelay: new Date("06/12/2020 06:00"),
  },
];

const sorted = data.sort((a, b) => {
  // one liner using conditional operator
  return a.startDate - b.startDate === 0
    ? a.startDateWithDelay - b.startDateWithDelay
    : a.startDate - b.startDate;
});

console.log(sorted);

In the same example if we had to sort over states in the order of 'LA', 'NY' & 'CH' then we could have done this too as shown in the below example.

const data = [
  {
    stateCode: "CH",
    startDate: new Date("06/12/2020 08:00"),
    startDateWithDelay: new Date("06/12/2020 08:00"),
  },
  {
    stateCode: "LA",
    startDate: new Date("06/12/2020 08:00"),
    startDateWithDelay: new Date("06/12/2020 08:30"),
  },
  {
    stateCode: "NY",
    startDate: new Date("06/12/2020 06:00"),
    startDateWithDelay: new Date("06/12/2020 06:00"),
  },
];

// Custom Sorting based on States in order of 'LA', 'NY' & 'CH'
const sorted = data.sort((a, b) => {
  const sCa = a.stateCode; //state code of a
  const sCb = b.stateCode; //state code of b
  return (sCa === 'LA' && sCb !== 'LA') || (sCa === 'NY' && sCb === 'CH') ? -1 : 
  (sCb === 'LA' && sCa !== 'LA') || (sCb === 'NY' && sCa === 'CH') ? 1 : 0;
});

console.log(sorted);

1 Comment

The last hard–coded sort would be much better using localeComare, e.g. (a, b) => a.stateCode.localeCompare(b.stateCode).
0
data = [
  {
    stateCode: 'CH',
    startDate: new Date('06/12/2020 08:00'),
    startDateWithDelay: new Date('06/12/2020 08:00'),
  },
  {
    stateCode: 'LA',
    startDate: new Date('06/12/2020 08:00'),
    startDateWithDelay: new Date('06/12/2020 08:30'),
  },
  {
    stateCode: 'NY',
    startDate: new Date('06/12/2020 06:00'),
    startDateWithDelay: new Date('06/12/2020 06:00')
  }
]

We can use the inbuilt sort function of the arrays, so we will compare the startDate if they are the same, we will sort on startDateWithDelay else continue sorting on startDate.

let data2 = data.sort((s1, s2) => s1.startDate == s2.startDate ? 
            s1.startDateWithDelay - s2.startDateWithDelay : 
            s1.startDate - s2.startDate); 

Once the sorting is done, we can use map to modify the result and join the sorted list of states for expected output.

let states = data2.map(s => s.stateCode).join(', ');

This will output the expected result.

NY, CH, LA

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.