0

I've got an object array which I have to group and sort:

[
  {
    id: 123,
    group: 'abc',
    metadata: {
      name: 'tom'
    },
    date: ISODate("2019-07-08T20:33:40.475Z")
  },
  {
    id: 456,
    group: 'def',
    metadata: {
      name: 'bob'
    },
    date: ISODate("2019-07-08T20:33:40.475Z")
  },
  {
    id: 789,
    group: 'def',
    metadata: {
      name: 'bob'
    },
    date: ISODate("2019-07-10T20:33:40.475Z")
  },
  {
    id: 234,
    group: 'ghi',
    metadata: {
      name: 'frank'
    },
    date: ISODate("2019-07-10T20:33:40.475Z")
  },
  {
    id: 567,
    group: 'abc',
    metadata: {
      name: 'tom'
    },
    date: ISODate("2019-07-10T20:33:40.475Z")
  }
]

Firstly I need to group the elements by the group value, then I need to sort the elements of this grouped array by date.

For grouping I've tried this:

const result = array.reduce(function (r, a) {
    r[a.group] = r[a.group] || [];
    r[a.group].push(a);
    return r;
}, Object.create(null));

But the result is not as expected and the elements are not sorted by date.

The result could/should look something like this:

[
  [
    {
      id: 123,
      group: 'abc',
      metadata: {
        name: 'tom'
      },
      date: ISODate("2019-07-08T20:33:40.475Z")
    },
    {
      id: 567,
      group: 'abc',
      metadata: {
        name: 'tom'
      },
      date: ISODate("2019-07-10T20:33:40.475Z")
    }
  ],
  [
    {
      id: 456,
      group: 'def',
      metadata: {
        name: 'bob'
      },
      date: ISODate("2019-07-08T20:33:40.475Z")
    },
    {
      id: 789,
      group: 'def',
      metadata: {
        name: 'bob'
      },
      date: ISODate("2019-07-10T20:33:40.475Z")
    }
  ],
  [
    {
      id: 234,
      group: 'ghi',
      metadata: {
        name: 'frank'
      },
      date: ISODate("2019-07-10T20:33:40.475Z")
    }
  ]
]
1
  • What is your ISODate function, and where are you trying to .sort the subarrays as desired? I don't see either of those in the code Commented Jul 10, 2019 at 21:49

2 Answers 2

0

Use reduce to group the values, and sort to sort them, using map as well due to the nested array structure.

const arr = [{id:123,group:'abc',metadata:{name:'tom'},date:"2019-07-08T20:33:40.475Z"},{id:456,group:'def',metadata:{name:'bob'},date:"2019-07-08T20:33:40.475Z"},{id:789,group:'def',metadata:{name:'bob'},date:"2019-07-10T20:33:40.475Z"},{id:234,group:'ghi',metadata:{name:'frank'},date:"2019-07-10T20:33:40.475Z"},{id:567,group:'abc',metadata:{name:'tom'},date:"2019-07-10T20:33:40.475Z"}];
const res = Object.values(arr.reduce((a, { group, ...r }) => {
  (a[group] = a[group] || []).push({ group, ...r });
  return a;
}, {})).map(e => e.sort(({ date: a }, { date: b }) => new Date(a) - new Date(b)));

console.log(res);
.as-console-wrapper { max-height: 100% !important; top: auto; }

(I've taken out the ISODate function and just kept the string date to make the snippet executable.)

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

Comments

0

I would suggest to use lodash.

var ISODate = function(str) { return str };

var data = [
  {
    id: 123,
    group: 'abc',
    metadata: {
      name: 'tom'
    },
    date: ISODate("2019-07-08T20:33:40.475Z")
  },
  {
    id: 456,
    group: 'def',
    metadata: {
      name: 'bob'
    },
    date: ISODate("2019-07-08T20:33:40.475Z")
  },
  {
    id: 789,
    group: 'def',
    metadata: {
      name: 'bob'
    },
    date: ISODate("2019-07-10T20:33:40.475Z")
  },
  {
    id: 234,
    group: 'ghi',
    metadata: {
      name: 'frank'
    },
    date: ISODate("2019-07-10T20:33:40.475Z")
  },
  {
    id: 567,
    group: 'abc',
    metadata: {
      name: 'tom'
    },
    date: ISODate("2019-07-10T20:33:40.475Z")
  }
]

console.log(
  _.mapValues(
    _.groupBy(data, 'group'),
    function(item) { return _.orderBy(item, ['date'], ['asc']) }
  )
)

https://codepen.io/anon/pen/bPzmOr

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.