Ashwanth Madhav
Ashwanth Madhav

Reputation: 1134

How to make unique array in javascript

I have an array of objects.

I need to get an array with a unique website name with the newest date.

Sample data

"data" : [ 
{
    "position" : 2,
    "website" : "abc.com",
    "owned" : false,
    "date" : "2020-05-06",
    "dateTime" : ISODate("2020-05-06T00:00:00.000Z")
}, 
{
    "position" : 3,
    "website" : "qwe.com",
    "owned" : false,
    "date" : "2020-05-06",
    "dateTime" : ISODate("2020-05-06T00:00:00.000Z")
}, 
{
    "position" : 1,
    "website" : "qwe.com",
    "owned" : false,
    "date" : "2020-04-06",
    "dateTime" : ISODate("2020-04-06T00:00:00.000Z")
}, 
{
    "position" : 6,
    "website" : "xyz.agency",
    "owned" : false,
    "date" : "2020-05-06",
    "dateTime" : ISODate("2020-05-06T00:00:00.000Z")
}, 
{
    "position" : 4,
    "website" : "opq.com",
    "owned" : true,
    "date" : "2020-05-06",
    "dateTime" : ISODate("2020-05-06T00:00:00.000Z")
}, 
{
    "position" : 2,
    "website" : "opq.com",
    "owned" : true,
    "date" : "2020-05-06",
    "dateTime" : ISODate("2020-05-06T00:00:00.000Z")
},
{
    "position" : 4,
    "website" : "opq.com",
    "owned" : true,
    "date" : "2020-04-01",
    "dateTime" : ISODate("2020-04-01T00:00:00.000Z")
}
]

Based on DateTime, position, and website. Need a MongoDB query or Javascript code.

(It's fine with DateTime and website. But getting stuck with position) (Extracting the object from which have the highest date and unique website name with top position)

Expected response

 "data" : [ 
{
    "position" : 2,
    "website" : "abc.com",
    "owned" : false,
    "date" : "2020-05-06",
    "dateTime" : ISODate("2020-05-06T00:00:00.000Z")
}, 
{
    "position" : 3,
    "website" : "qwe.com",
    "owned" : false,
    "date" : "2020-05-06",
    "dateTime" : ISODate("2020-05-06T00:00:00.000Z")
}, 
{
    "position" : 6,
    "website" : "xyz.agency",
    "owned" : false,
    "date" : "2020-05-06",
    "dateTime" : ISODate("2020-05-06T00:00:00.000Z")
}, 
{
    "position" : 2,
    "website" : "opq.com",
    "owned" : true,
    "date" : "2020-05-06",
    "dateTime" : ISODate("2020-05-06T00:00:00.000Z")
}

],

Upvotes: 0

Views: 62

Answers (2)

Nithish
Nithish

Reputation: 6019

Using the below utility you can achieve the required output in javascript. Hope this will help

const getUniqueWebsites = data => {
  return data.reduce((result, d) => {
      if(result[d.website]) {
          if(new Date(result[d.website].dateTime).getTime() < new Date(d.dateTime).getTime()){
              result[d.website] = d;
          }
          else if(new Date(result[d.website].dateTime).getTime() === new Date(d.dateTime).getTime() && 
          (result[d.website].position) > d.position){
            result[d.website] = d;

          }
      } else {
          result[d.website] = d;
      }
return result;
  },{})
}

let data = [
  {
    "position": 2,
    "website": "abc.com",
    "owned": false,
    "date": "2020-05-06",
    "dateTime": "2020-05-06T00:00:00.000Z"
  },
  {
    "position": 3,
    "website": "qwe.com",
    "owned": false,
    "date": "2020-05-06",
    "dateTime": "2020-05-06T00:00:00.000Z"
  },
  {
    "position": 1,
    "website": "qwe.com",
    "owned": false,
    "date": "2020-04-06",
    "dateTime": "2020-04-06T00:00:00.000Z"
  },
  {
    "position": 6,
    "website": "xyz.agency",
    "owned": false,
    "date": "2020-05-06",
    "dateTime": "2020-05-06T00:00:00.000Z"
  },
  {
    "position": 4,
    "website": "opq.com",
    "owned": true,
    "date": "2020-05-06",
    "dateTime": "2020-05-06T00:00:00.000Z"
  },
  {
    "position": 2,
    "website": "opq.com",
    "owned": true,
    "date": "2020-05-06",
    "dateTime": "2020-05-06T00:00:00.000Z"
  },
  {
    "position": 4,
    "website": "opq.com",
    "owned": true,
    "date": "2020-04-01",
    "dateTime": "2020-04-01T00:00:00.000Z"
  }
]

let result = getUniqueWebsites(data)
console.log(Object.values(result))

Upvotes: 1

Xuan Son NGUYEN
Xuan Son NGUYEN

Reputation: 406

If you want to do from JS level (warning! low performance):

var maxDate = {};  // temporary variable to store latest date of a website
var websites = data
  .map(entry => {
    if ((maxDate[entry.website] || 0) < entry.dateTime.getTime()) {
      maxDate[entry.website] = entry.dateTime.getTime();
    }
    return entry;
  })
  .filter(entry => {
    return maxDate[entry.website] === entry.dateTime.getTime();
  });

If you want to do that with mongodb query: Select Max() with "group by" in mongodb

Upvotes: 0

Related Questions