-1

i have the data structure like below,

const items = {
    id: '1',
    Orders: [
        {
             id: '1',
             title: 'Order1',
             startDate: "2019-08-13T00:00:00.000Z",
             status: 'new',
        }
        {
             id: '2',
             title: 'Order2',
             startDate: "2020-08-13T00:00:00.000Z",
             status: 'done',
        }
    ],
    subItems: [
        {
            id: '1',
            Orders: [
                {
                    id: '1',
                    title: 'subitem-order1',
                    status: 'new',
                    startDate: '2019-08-13T00:00:00.000Z',
                }
                {
                    id: '2',
                    title: 'subitem-order2',
                    status: 'new',
                    startDate: '2020-08-13T00:00:00.000Z',
                }
            ]
        }
    ]
}

I want to order the orders by startdate in ascending order and subitem orders by startdate in ascending order.

so the output should be something like below,

const items  = {
    orders: [
        {
             id: '2',
             title: 'Order2',
             startDate: "2020-08-13T00:00:00.000Z",
             status: 'done',
        },
        {
             id: '1',
             title: 'Order1',
             startDate: "2019-08-13T00:00:00.000Z",
             status: 'new',
         },
     ]
     subItems: [
         {
              id: '2',
              title: 'subitem-order2',
              status: 'new',
              startDate: '2020-08-13T00:00:00.000Z',
         },
         {
              id: '1',
              title: 'Order1',
              startDate: "2019-08-13T00:00:00.000Z",
              status: 'new',
         },
     ]
}

How can i group the orders in ascending order based on their startdate and subitems orders in ascending order based on their startdate. could someone help me with this. thanks.

someuser2491
  • 1,848
  • 5
  • 27
  • 63
  • 1
    [Array.prototype.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) – Pointy Aug 14 '20 at 13:04
  • Does this answer your question? [Sort array by ISO 8601 date](https://stackoverflow.com/questions/12192491/sort-array-by-iso-8601-date) – Emile Bergeron Aug 14 '20 at 13:46

2 Answers2

1

Fortunately your startDate is an ISO datetime, so an alphabetical sort will deliver the correct temporal ordering. Let's exploit this!

Remember that the key by which you are sorting is a string, and not a number. A convenient way to sort by a string key is using localeCompare, which has the useful feature of taking two strings and returning a number appropriate for sorting.

Because the sorting is simple to deliver with localeCompare, you can do each list's sorting as a one-liner, which allows you to "build" the result object in an easy-to-understand way, as follows:

const rawItems  = {
    orders: [
        {
             id: '2',
             title: 'Order2',
             startDate: "2020-08-13T00:00:00.000Z",
             status: 'done',
        },
        {
             id: '1',
             title: 'Order1',
             startDate: "2019-08-13T00:00:00.000Z",
             status: 'new',
         },
     ],
     subItems: [
         {
              id: '2',
              title: 'subitem-order2',
              status: 'new',
              startDate: '2020-08-13T00:00:00.000Z',
         },
         {
              id: '1',
              title: 'Order1',
              startDate: "2019-08-13T00:00:00.000Z",
              status: 'new',
         },
     ]
}

const items = {
    orders: rawItems.orders.sort(
       (order1,order2) => order1.startDate.localeCompare(order2.startDate)
    ),
    subitems: rawItems.subItems.sort(
       (sub1,sub2) => sub1.startDate.localeCompare(sub2.startDate)
    ),

}

console.log(items)

In the question you repeatedly specify "ascending" order, i.e. small values first, then big values. However the example answer you give is of descending order.

The example answer I have provided does ascending, as you specified. If you meant "descending", then just negate the localeCompare values as follows:

       (order1,order2) => -order1.startDate.localeCompare(order2.startDate)

and

       (sub1,sub2) => -sub1.startDate.localeCompare(sub2.startDate)
ProfDFrancis
  • 8,816
  • 1
  • 17
  • 26
0

You can modify the Array.prototype.sort method to do just that. Convert your start dates to time in milliseconds and sort based on that. The order in which you specify -1 and 1 will give you ASC or DESC order.

const items = {
    Orders: [
        {
             id: '1',
             title: 'Order1',
             startDate: "2019-08-13T00:00:00.000Z",
             status: 'new',
        },
        {
             id: '2',
             title: 'Order2',
             startDate: "2020-08-13T00:00:00.000Z",
             status: 'done',
        }
    ],
    subItems: [
        {
            Orders: [
                {
                    id: '1',
                    title: 'subitem-order1',
                    status: 'new',
                    startDate: '2019-08-13T00:00:00.000Z',
                },
                {
                    id: '2',
                    title: 'subitem-order2',
                    status: 'new',
                    startDate: '2020-08-13T00:00:00.000Z',
                }
            ]
        }
    ]
}

items.Orders.sort((a,b) => {
  let TimeA = new Date(a.startDate).getTime();
  let TimeB = new Date(b.startDate).getTime();
  return TimeA > TimeB ? 1 : TimeA < TimeB ? -1 : 0;
})

items.subItems[0].Orders.sort((a,b) => {
  let TimeA = new Date(a.startDate).getTime();
  let TimeB = new Date(b.startDate).getTime();
  return TimeA > TimeB ? 1 : TimeA < TimeB ? -1 : 0;
})

console.log(items);
Michael
  • 1,454
  • 3
  • 19
  • 45