Sort an array with respect to value of one property and date object to fetch recent entry using javascript

Viewed 56

I need to get a recent entry among from multiple entries.

let items = [{Fruit: "Apple",date: 1592809121000},
{Fruit: "Orange",date: 1592564167000},
{Fruit: "Apple",date: 1592566351000},
{Fruit: "Orange",date: 1592809121000},
{Fruit: "Apple",date: 1592564167000},
{Fruit: "Apple",date: 1593153998000},
{Fruit: "Orange",date: 1592893249000},
{Fruit: "Grapes",date: 1592565214000}]

Expected output:

let items = [{
  Fruit: "Apple",
  date: recent entry
}, {
  Fruit: "Orange",
  date: recent entry
}, {
  Fruit: "Grapes",
  date: recent entry
}]

Tried code to sort with date but it is sorting among all fruits but i want to sort only among specific fruit to get latest entry with timestamp and remove other entries from array

// Sort by date and show recent first
items = items.sort(function(a, b) { 
  return (new Date(b.date))- (new Date(a.date));
});
4 Answers

You could reduce the array and take only the greater date of each fruit.

let array = [{ Fruit: "Apple", date: 1592809121000 }, { Fruit: "Orange", date: 1592564167000 }, { Fruit: "Apple", date: 1592566351000 }, { Fruit: "Orange", date: 1592809121000 }, { Fruit: "Apple",  date: 1592564167000 }, { Fruit: "Apple", date: 1593153998000 }, { Fruit: "Orange", date: 1592893249000 }, { Fruit: "Grapes", date: 1592565214000 }],
    result = Object.values(array.reduce((r, o) => {
        if (!r[o.Fruit] || r[o.Fruit].date < o.date) r[o.Fruit] = o;
        return r;
    }, {}));

console.log(result);

We can use Array.reduce() to create a new array with all the fruits in them. Inside the collection we can then see if it exists. And if it exists replace it if its more recent or do nothing.

const fruits = [
  {Fruit: "Apple", date: 1592809121000},
  {Fruit: "Orange", date: 1592564167000},
  {Fruit: "Apple", date: 1592566351000},
  {Fruit: "Orange", date: 1592809121000},
  {Fruit: "Apple", date: 1592564167000},
  {Fruit: "Apple", date: 1593153998000},
  {Fruit: "Orange", date: 1592893249000},
  {Fruit: "Grapes", date: 1592565214000},
];

// Get the most recent fruits
const mostRecent = fruits.reduce((all, fruit) => {
  // Check if it exists
  if(all[fruit.Fruit]) {
    // If the is more recent replace the current one
    all[fruit.Fruit] = fruit.date > all[fruit.Fruit].date ? fruit : all[fruit.Fruit];
  }else{
    // If it doesn't exist add it to our collection
    all[fruit.Fruit] = fruit;
  }
  
  return all;
}, {});

console.log(mostRecent);

You need a reduce or filter after the sort

const arr = [{Fruit: "Apple",date: 1592809121000},
{Fruit: "Orange",date: 1592564167000},
{Fruit: "Apple",date: 1592566351000},
{Fruit: "Orange",date: 1592809121000},
{Fruit: "Apple",date: 1592564167000},
{Fruit: "Apple",date: 1593153998000},
{Fruit: "Orange",date: 1592893249000},
{Fruit: "Grapes",date: 1592565214000}]

const newArr = arr.sort((a,b) => a.date-b.date)
.reduce((acc,item) => {
  if (!acc.find(accItem => accItem.Fruit === item.Fruit)) acc.push(item)
  return acc
},[] )
console.log(newArr)

You COULD reduce testing dates too as shown in another answer

You can use a Map to key your data by the fruit field, and then iterate the matching entries keeping the minimum of the date values:

let data = [{Fruit: "Apple",date: 1592809121000},{Fruit: "Orange",date: 1592564167000},{Fruit: "Apple",date: 1592566351000},{Fruit: "Orange",date: 1592809121000},{Fruit: "Apple",date: 1592564167000},{Fruit: "Apple",date: 1593153998000},{Fruit: "Orange",date: 1592893249000},{Fruit: "Grapes",date: 1592565214000}];

let map = new Map(data.map(o => [o.Fruit, o]));
data.forEach(o => o.date < map.get(o.Fruit).date && map.set(o.Fruit, o));

let result = Array.from(map.values());
console.log(result);

Related