5

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
      }]
Vishnu Shenoy
  • 862
  • 5
  • 18
  • Can you please add the code you have written? – Md Sabbir Alam Dec 29 '20 at 08:13
  • You can simply use `Array.prototype.sort`; it would be something like: `array.sort((itemA, itemB) => { /* compare itemA.date with itemB.date: if itemA.date is older than itemB.date return -1, if it is equal return 0 and if it is more recent return 1 */ })` – secan Dec 29 '20 at 08:18
  • @sabbir.alam the OP did share his code; his question is how to convert it into ES6 syntax. ;) – secan Dec 29 '20 at 08:21
  • @secan sorry i didn't see the code part. My bad. – Md Sabbir Alam Dec 29 '20 at 08:23
  • When the date is the same, does it matter which item is returned? For example, would it be fine to return the item with ID 1 instead of the one with ID 3? – secan Dec 29 '20 at 08:39
  • 1
    Also your expected output is wrong. Last item should be "2016-01-23T17:18:44.258843Z" – Isa Ataseven Dec 29 '20 at 09:04
  • Does this answer your question? [How to sort an array by a date property](https://stackoverflow.com/questions/10123953/how-to-sort-an-array-by-a-date-property) – Daniel_Knights Dec 29 '20 at 09:18

6 Answers6

1

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);
Kevin Zhang
  • 1,012
  • 6
  • 14
0

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.

Aniruddha Shevle
  • 4,602
  • 4
  • 22
  • 36
0

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))
}
Isa Ataseven
  • 166
  • 1
  • 10
0
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

Vishnu Shenoy
  • 862
  • 5
  • 18
0

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.

Zang wei
  • 168
  • 1
  • 8
0

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));
Siva K V
  • 10,561
  • 2
  • 16
  • 29