get latest date for each day in an array of object?

Viewed 165

i have array of object which are sorted based on date/time, I have to form an array of object with latest data from each date?. I'm getting the solution with for loop but I need to use es6 and above, please help me with a better and advanced solution.

var array = [
  {
    "id": 1,
    "date": "2016-01-15T16:18:44.258843Z",
    "status": "NEW",
    "request": 4
  },
 {
    "id": 2,
    "date": "2016-01-15T18:18:44.258843Z",
    "status": "NEW",
    "request": 4
  },
 {
    "id": 3,
    "date": "2016-01-15T20:18:44.258843Z",
    "status": "NEW",
    "request": 4
  },
  {
    "id": 4,
    "date": "2016-01-19T16:18:44.258843Z",
    "status": "STD",
    "request": 4
  },
  {
    "id": 6,
    "date": "2016-01-23T17:18:44.258843Z",
    "status": "FOR",
    "request": 4
  },
{
    "id": 5,
    "date": "2016-01-23T16:18:44.258843Z",
    "status": "FOR",
    "request": 4
  }]
const list = filter(array, el => (el.date));
   latestDate = list[0]?.date.slice(0, 10);
   latestResponse.push(res[0]);
 for (let i = array.length - 1; i > 0; i--) {
      if (this.latestDate !== array[i].date.slice(0, 10)) {
      latestDate = (array[i].date).slice(0, 10);
        latestResponse.push(res[i]);
      }
    }

expected Output

var array = [
     {
        "id": 3,
        "date": "2016-01-15T20:18:44.258843Z",
        "status": "NEW",
        "request": 4
      },
      {
        "id": 4,
        "date": "2016-01-19T16:18:44.258843Z",
        "status": "STD",
        "request": 4
      },
    {
        "id": 5,
        "date": "2016-01-23T17:18:44.258843Z",
        "status": "FOR",
        "request": 4
      }]
6 Answers

Here is the code, use reduce method.

var array = [
    {
        "id": 1,
        "date": "2016-01-15T16:18:44.258843Z",
        "status": "NEW",
        "request": 4
    },
    {
        "id": 2,
        "date": "2016-01-15T18:18:44.258843Z",
        "status": "NEW",
        "request": 4
    },
    {
        "id": 3,
        "date": "2016-01-15T20:18:44.258843Z",
        "status": "NEW",
        "request": 4
    },
    {
        "id": 4,
        "date": "2016-01-19T16:18:44.258843Z",
        "status": "STD",
        "request": 4
    },
    {
        "id": 6,
        "date": "2016-01-23T17:18:44.258843Z",
        "status": "FOR",
        "request": 4
    },
    {
        "id": 5,
        "date": "2016-01-23T16:18:44.258843Z",
        "status": "FOR",
        "request": 4
    }];

console.clear();
let results = array.reduce((acc: any, cur: any) => {
    let curDate = new Date(cur.date);
    let curDateStr = curDate.getFullYear() + '-' + (curDate.getMonth() + 1) + '-' + curDate.getDate();
    let existDateObj = acc.find(f => f.dStr === curDateStr);
    if (existDateObj) {
        let existDate = new Date(existDateObj.date);
        if (curDate.getTime() > existDate.getTime()) {
            acc = acc.filter(f => f.id !== existDateObj.id);
            acc.push(Object.assign(cur, { dStr: curDateStr }));
        }
    } else {
        acc.push(Object.assign(cur, { dStr: curDateStr }));
    }

    return acc;
}, []);

console.log(results);

const latestResponse = [];
    const list = filter(res, el => (el.date));
    let latestDate = moment(list[0]?.date).format("DD/MM/YYYY");
    [...res].reverse().filter(el => {
      if (latestDate !== moment(el.date).format("DD/MM/YYYY")) {
        latestDate = moment(el.date).format("DD/MM/YYYY");
        latestResponse.push(el);
      }
    })

used moment to format the date, and used filter to generate the new array

Instead of using multiple array methods/loops, this can be done using a single for of loop as follows,

function getLatestDateInfo(array) {
  let obj = {};
  for (const item of array) {
    var today = new Date(item.date);
    var year = today.getFullYear();
    var month = today.getMonth() + 1;
    var day = today.getDate();
    var mainDate = day + "-" + month + "-" + year;
    obj = {
        ...obj,
        [mainDate]: { ...item },
    }
  }
  return Object.values(obj);
}

The above solution is based on the assumption that the array of objects are sorted based on date/time, as this is mentioned in the question.

You can try this. Sort, group, get

array.sort(function(a,b){
  return new Date(a.date) - new Date(b.date);
});

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

for (const n in result) {
    newArray.push(result[n].slice(-1))
}

var array = [
  {
    "id": 1,
    "date": "2016-01-15T16:18:44.258843Z",
    "status": "NEW",
    "request": 4
  },
 {
    "id": 2,
    "date": "2016-01-15T18:18:44.258843Z",
    "status": "NEW",
    "request": 4
  },
 {
    "id": 3,
    "date": "2016-01-15T20:18:44.258843Z",
    "status": "NEW",
    "request": 4
  },
  {
    "id": 4,
    "date": "2016-01-19T16:18:44.258843Z",
    "status": "STD",
    "request": 4
  },
  {
    "id": 6,
    "date": "2016-01-23T17:18:44.258843Z",
    "status": "FOR",
    "request": 4
  },
{
    "id": 5,
    "date": "2016-01-23T16:18:44.258843Z",
    "status": "FOR",
    "request": 4
  }];
  const sortedLatestArray = array.sort((a, b) => {
    if(a.date > b.date) {
      return -1;
    } else if (a.date === b.date){
      return 0;
    } else {
      return 1;
    }
  }).filter((item, i, sortedArray) => {
    if(i) {
      const prevItem = sortedArray[i - 1];
      const prevItemDate = prevItem.date.slice(0, 10);
      const currentItemDate = item.date.slice(0, 10);
      return currentItemDate !== prevItemDate;
    }
    return true;
  }).reverse();
  
  console.log(sortedLatestArray);

Sort array latest to oldest, and then remove duplicated date item by comparing former Item and current Item using filter method, finally reverse array to make result sorted as oldest to latest.

Use forEach and build an object with keys as date. If the same date exist, then replace with latest date-time.

const refine = (arr) => {
  const res = {};
  arr.forEach((item) => {
    const date_str = item.date.split('T')[0];
    res[date_str] ??= { ...item };
    if (new Date(item.date) > new Date(res[date_str].date)) {
      res[date_str].date = item.date;
    }
  });
  return Object.values(res);
};

var array = [
  {
    id: 1,
    date: "2016-01-15T16:18:44.258843Z",
    status: "NEW",
    request: 4,
  },
  {
    id: 2,
    date: "2016-01-15T18:18:44.258843Z",
    status: "NEW",
    request: 4,
  },
  {
    id: 3,
    date: "2016-01-15T20:18:44.258843Z",
    status: "NEW",
    request: 4,
  },
  {
    id: 4,
    date: "2016-01-19T16:18:44.258843Z",
    status: "STD",
    request: 4,
  },
  {
    id: 6,
    date: "2016-01-23T17:18:44.258843Z",
    status: "FOR",
    request: 4,
  },
  {
    id: 5,
    date: "2016-01-23T16:18:44.258843Z",
    status: "FOR",
    request: 4,
  },
];
console.log(refine(array));

Related