1

I have an array of objects and I want to sort it by date (in this case it's the property with occurredAt in it's name). Here is the array:

const arr = [
  {
    EmailCampaignEvents.campaignRef: "test6example1",
    EmailCampaignEvents.campaignSentAt: "2021-04-09T13:19:24.000",
    EmailCampaignEvents.customerRef: "Customer/activityTest10",
    EmailCampaignEvents.emailRef: "Email/9374eaee0713f36a247b0d0c863e920b",
    EmailCampaignEvents.eventType: "delivery",
    EmailCampaignEvents.occurredAt: "2021-04-09T13:19:25.000",
  },
  {
    Events.occurredAt: "2017-01-11T17:29:57.000",
    Events.productRef: "Event/201-13",
    Events.relatedEntityRefFlat: "Customer/201-5645307",
    Events.transactionCurrency: "SEK",
    Events.transactionItemCount: "4",
    Events.transactionItemPrice: "235.85",
    Events.type: "as.commerce.transaction.completed",
    relatedEventName: "Hammarby-Östersunds FK",
  },
  {
    Events.occurredAt: "2018-01-11T17:29:57.000",
    Events.productRef: "Event/201-13",
    Events.relatedEntityRefFlat: "Customer/201-5645307",
    Events.transactionCurrency: "SEK",
    Events.transactionItemCount: "2",
    Events.transactionItemPrice: "135.85",
    Events.type: "as.commerce.transaction.completed",
    relatedEventName: "Hammarby-Östersunds FK",
  },
];

Note that in the first object I have EmailCampaignEvents.occurredAt and in the rest two I have a property like this Events.occurredAt. Is it possible to sort this array somehow? Any example will be appreciated!

3 Answers 3

2

The crux of the problem is the variable key names of the objects that store the occurredAt date values, you can define a custom method to get the values by checking for the substring in every object's keys.

const getOccurredAt = (obj) => {
  const key = Object.keys(obj).filter(k => k.includes('occurredAt'))[0];
  if (key) {
    return obj[key];
  }
  return null; // Set a default based on your use-case
}

arr.sort((x, y) => {
  const xVal = getOccurredAt(x);
  const yVal = getOccurredAt(y);
  return new Date(yVal) - new Date(xVal);
})

This would solve your problem, but I would definitely recommend having consistent key names for the same data across all objects, if possible.

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

Comments

1

If there really are only 2 possibilities, you could just use a boolean or to fallback from the first to the second possibility:

const arr = [
  {
    "EmailCampaignEvents.campaignRef": "test6example1",
    "EmailCampaignEvents.campaignSentAt": "2021-04-09T13:19:24.000",
    "EmailCampaignEvents.customerRef": "Customer/activityTest10",
    "EmailCampaignEvents.emailRef": "Email/9374eaee0713f36a247b0d0c863e920b",
    "EmailCampaignEvents.eventType": "delivery",
    "EmailCampaignEvents.occurredAt": "2021-04-09T13:19:25.000",
  },
  {
    "Events.occurredAt": "2017-01-11T17:29:57.000",
    "Events.productRef": "Event/201-13",
    "Events.relatedEntityRefFlat": "Customer/201-5645307",
    "Events.transactionCurrency": "SEK",
    "Events.transactionItemCount": "4",
    "Events.transactionItemPrice": "235.85",
    "Events.type": "as.commerce.transaction.completed",
    "relatedEventName": "Hammarby-Östersunds FK",
  },
  {
    "Events.occurredAt": "2018-01-11T17:29:57.000",
    "Events.productRef": "Event/201-13",
    "Events.relatedEntityRefFlat": "Customer/201-5645307",
    "Events.transactionCurrency": "SEK",
    "Events.transactionItemCount": "2",
    "Events.transactionItemPrice": "135.85",
    "Events.type": "as.commerce.transaction.completed",
    "relatedEventName": "Hammarby-Östersunds FK",
  },
];

const result = arr.sort((a,b) => {
  const aVal = new Date(a["EmailCampaignEvents.occurredAt"] || a["Events.occurredAt"]);
  const bVal = new Date(b["EmailCampaignEvents.occurredAt"] || b["Events.occurredAt"]);
  return aVal - bVal;
});

console.log(result);

1 Comment

All three answers are good, but this one suits best for my code structure. Thanks for your effort!
1

Use Array.prototype.sort() with a custom sort function. You can use Object.keys() to find object keys that end in .occurredAt. Like so:

const arr = [
  {
    "EmailCampaignEvents.campaignRef": "test6example1",
    "EmailCampaignEvents.campaignSentAt": "2021-04-09T13:19:24.000",
    "EmailCampaignEvents.customerRef": "Customer/activityTest10",
    "EmailCampaignEvents.emailRef": "Email/9374eaee0713f36a247b0d0c863e920b",
    "EmailCampaignEvents.eventType": "delivery",
    "EmailCampaignEvents.occurredAt": "2021-04-09T13:19:25.000",
  },
  {
    "Events.occurredAt": "2017-01-11T17:29:57.000",
    "Events.productRef": "Event/201-13",
    "Events.relatedEntityRefFlat": "Customer/201-5645307",
    "Events.transactionCurrency": "SEK",
    "Events.transactionItemCount": "4",
    "Events.transactionItemPrice": "235.85",
    "Events.type": "as.commerce.transaction.completed",
    relatedEventName: "Hammarby-Östersunds FK",
  },
  {
    "Events.occurredAt": "2018-01-11T17:29:57.000",
    "Events.productRef": "Event/201-13",
    "Events.relatedEntityRefFlat": "Customer/201-5645307",
    "Events.transactionCurrency": "SEK",
    "Events.transactionItemCount": "2",
    "Events.transactionItemPrice": "135.85",
    "Events.type": "as.commerce.transaction.completed",
    relatedEventName: "Hammarby-Östersunds FK",
  },
]

arr.sort((a, b) => {
  const keyA = Object.keys(a).find((key) => key.endsWith('.occurredAt'))
  const keyB = Object.keys(b).find((key) => key.endsWith('.occurredAt'))
  const dateA = new Date(a[keyA])
  const dateB = new Date(b[keyB])
  return dateA - dateB // oldest to newest
})

console.log(arr)

Note that Array.prototype.sort() modifies the original array. You can use e.g. arr.slice().sort() to first create a copy of the array and then sort the copied array.

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.