Jignesh Raval
Jignesh Raval

Reputation: 607

JavaScript - Group items from Array of Objects or Records by Date

I need help to display array items grouped by Date. I have following array with few items and each item has "today" field.

var originalArray = [
        {title: "New Three 123", status: "pending", isDone: false, today: "2018-02-20T16:40:17.759Z", _id: "Eyt44n1svxIjOn5Y"},
        {title: "My First card", status: "pending", isDone: false, today: "2018-02-21T13:00:13.979Z", _id: "UlSoOrLBjX2RldgQ"},
        {title: "Sun Pharma", status: "completed", isDone: true, today: "2018-02-20T16:41:19.040Z", _id: "VbBEyndCIhPDB1Uf"},
        {title: "Design News", status: "pending", isDone: false, today: "2018-02-21T13:00:07.730Z", _id: "rpW4bVIYWjlPMgk6"},
        {title: "Amul India sddsd", status: "pending", isDone: false, today: "2018-02-20T16:41:13.087Z", _id: "uyISWNb7vapmRrNG"}
        ]

Required output is records needs to be grouped by date written in "today" key field of array items:

    var outputRequired = {
    '2018,2,20' : [
        {title: "New Three 123", status: "pending", isDone: false, today: "2018-02-20T16:40:17.759Z", _id: "Eyt44n1svxIjOn5Y"},     
        {title: "Sun Pharma", status: "completed", isDone: true, today: "2018-02-20T16:41:19.040Z", _id: "VbBEyndCIhPDB1Uf"},       
        {title: "Amul India sddsd", status: "pending", isDone: false, today: "2018-02-20T16:41:13.087Z", _id: "uyISWNb7vapmRrNG"}
    ],
    '2018,2,21' : [
        {title: "My First card", status: "pending", isDone: false, today: "2018-02-21T13:00:13.979Z", _id: "UlSoOrLBjX2RldgQ"},
        {title: "Design News", status: "pending", isDone: false, today: "2018-02-21T13:00:07.730Z", _id: "rpW4bVIYWjlPMgk6"}
    ]
}

Please guide me how can I achieve this output.

Thanks, Jignesh Raval

Upvotes: 1

Views: 753

Answers (4)

EugenSunic
EugenSunic

Reputation: 13693

Approach using javascript reduce function:

var arr = [{
    title: "New Three 123",
    status: "pending",
    isDone: false,
    today: "2018-02-20T16:40:17.759Z",
    _id: "Eyt44n1svxIjOn5Y"
  },
  {
    title: "My First card",
    status: "pending",
    isDone: false,
    today: "2018-02-21T13:00:13.979Z",
    _id: "UlSoOrLBjX2RldgQ"
  },
  {
    title: "Sun Pharma",
    status: "completed",
    isDone: true,
    today: "2018-02-20T16:41:19.040Z",
    _id: "VbBEyndCIhPDB1Uf"
  },
  {
    title: "Design News",
    status: "pending",
    isDone: false,
    today: "2018-02-21T13:00:07.730Z",
    _id: "rpW4bVIYWjlPMgk6"
  },
  {
    title: "Amul India sddsd",
    status: "pending",
    isDone: false,
    today: "2018-02-20T16:41:13.087Z",
    _id: "uyISWNb7vapmRrNG"
  }
];

function adjustDate(date) {
  const year = date.substring(0, 4);
  const month = date.substring(5, 7);
  const day = date.substring(8, 10);
  return year + ',' + month + ',' + day;
}

const output = arr.reduce((acc, x) => {
  const dateKey = adjustDate(x.today);

  if (!acc[dateKey]) {
    acc = {
      ...acc,
      [dateKey]: [x]
    }
    return acc;
  }

  return acc = {
    ...acc,
    [dateKey]: [...acc[dateKey], x]
  }
}, {})


console.log('Output', output);

Upvotes: 0

Rafael Paulino
Rafael Paulino

Reputation: 581

The easiest way I find is using a library called lodash, being more specific, the _.groupBy function:

var originalArray = [
        {title: "New Three 123", status: "pending", isDone: false, today: "2018-02-20T16:40:17.759Z", _id: "Eyt44n1svxIjOn5Y"},
        {title: "My First card", status: "pending", isDone: false, today: "2018-02-21T13:00:13.979Z", _id: "UlSoOrLBjX2RldgQ"},
        {title: "Sun Pharma", status: "completed", isDone: true, today: "2018-02-20T16:41:19.040Z", _id: "VbBEyndCIhPDB1Uf"},
        {title: "Design News", status: "pending", isDone: false, today: "2018-02-21T13:00:07.730Z", _id: "rpW4bVIYWjlPMgk6"},
        {title: "Amul India sddsd", status: "pending", isDone: false, today: "2018-02-20T16:41:13.087Z", _id: "uyISWNb7vapmRrNG"}
        ]

var outputArray = _.groupBy(originalArray, function(item) {
    return item.today.substr(0, 10)
        .replace(/-/g, ',')
        .replace(/([$,])(0)(\d[,^])/, '$1$3')
    });

console.log(outputArray);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.js"></script>

Upvotes: 0

void
void

Reputation: 36703

You can use .reduce to get the desired result. Set initialValue to {} and in each iteration check if the date key exists or not. If it exists append to the array or else create a new array inside accumulator.

var data = originalArray.reduce(
  (acc, el)=>{
    var today = el.today.split("T")[0].replace(/-/g, ",");
    if(acc.hasOwnProperty(today)) acc[today].push(el);
    else acc[today] = [el];
    return acc;
  }, {}
)

See the working code here:

var originalArray = [{
    title: "New Three 123",
    status: "pending",
    isDone: false,
    today: "2018-02-20T16:40:17.759Z",
    _id: "Eyt44n1svxIjOn5Y"
  },
  {
    title: "My First card",
    status: "pending",
    isDone: false,
    today: "2018-02-21T13:00:13.979Z",
    _id: "UlSoOrLBjX2RldgQ"
  },
  {
    title: "Sun Pharma",
    status: "completed",
    isDone: true,
    today: "2018-02-20T16:41:19.040Z",
    _id: "VbBEyndCIhPDB1Uf"
  },
  {
    title: "Design News",
    status: "pending",
    isDone: false,
    today: "2018-02-21T13:00:07.730Z",
    _id: "rpW4bVIYWjlPMgk6"
  },
  {
    title: "Amul India sddsd",
    status: "pending",
    isDone: false,
    today: "2018-02-20T16:41:13.087Z",
    _id: "uyISWNb7vapmRrNG"
  }
];

var data = originalArray.reduce(
  (acc, el)=>{
    var today = el.today.split("T")[0].replace(/-/g, ",");
    if(acc.hasOwnProperty(today)) acc[today].push(el);
    else acc[today] = [el];
    return acc;
  }, {}
)

console.log(data);

Upvotes: 1

L&#233;o R.
L&#233;o R.

Reputation: 2698

If you want do this without external lib try this :

var groupBy = function(xs, key) {
  return xs.reduce(function(rv, x) {
    (rv[x[key]] = rv[x[key]] || []).push(x);
    return rv;
  }, {});
};
var originalArray = [
        {title: "New Three 123", status: "pending", isDone: false, today: "2018-02-20T16:40:17.759Z", _id: "Eyt44n1svxIjOn5Y"},
        {title: "My First card", status: "pending", isDone: false, today: "2018-02-21T13:00:13.979Z", _id: "UlSoOrLBjX2RldgQ"},
        {title: "Sun Pharma", status: "completed", isDone: true, today: "2018-02-20T16:41:19.040Z", _id: "VbBEyndCIhPDB1Uf"},
        {title: "Design News", status: "pending", isDone: false, today: "2018-02-21T13:00:07.730Z", _id: "rpW4bVIYWjlPMgk6"},
        {title: "Amul India sddsd", status: "pending", isDone: false, today: "2018-02-20T16:41:13.087Z", _id: "uyISWNb7vapmRrNG"}
        ];


console.log(groupBy(originalArray, 'today'));

Upvotes: 0

Related Questions