1

I have an array of objects.

I need to get an array with unique website name with 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 datetTime, position and website. Need a mongoDB query or Javascript code. (Earlier its with dateTime and website)

(Extracting the object from which have 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")
}

],

1
  • So data is an array field inside each document ? Or data is an array of docs ? Should we take data is an array field ? Commented Jun 3, 2020 at 16:45

3 Answers 3

2

use forEach and build an object to handle dulicates and maintain only new date item. Get Object.values from above object.

const uniq = (arr) => {
  const res = {};
  arr.forEach((item) => {
    if (
      !res[item.website] ||
      new Date(item.dateTime) > new Date(res[item.website].dateTime)
    ) {
      res[item.website] = { ...item };
    }
  });
  return Object.values(res);
};

// Update uniq2
const uniq2 = (arr) => {
  const res = {};
  arr.forEach((item) => {
    if (!res[item.website]) {
      res[item.website] = { ...item };
    } else {
      if (new Date(item.dateTime) > new Date(res[item.website].dateTime)) {
        res[item.website].dateTime = item.dateTime;
      }
      if (item.position > res[item.website].position) {
        res[item.website].position = item.position;
      }
    }
  });
  return Object.values(res);
};


const data2 = [
  {
    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: 1,
    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: 3,
    website: "opq.com",
    owned: true,
    date: "2020-04-01",
    dateTime: "2020-04-01T00:00:00.000Z",
  },
];


console.log(uniq2(data2));

Sign up to request clarification or add additional context in comments.

7 Comments

Is it new Date(item.dateTime) > new Date(res[item.website].dateTime) ?
Oh yes I meant that. Good catch @ashwanth.
I just updated my question. Can you please check it. I have to make unique it with top position.
@AshwanthMadhav, Do you mean to say, for the one web site, need to extract the "latest date" and "top position" (position being small number)? Both attributes from the different objects?
If this is case, use uniq2 method which I just updated in answer.
|
2

In javascript you can reduce it:

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

var result = data.reduce((acc, elem)=>{
  isPresent = acc.findIndex(k=>k.website==elem.website);
  if(isPresent==-1){
     acc.push(elem);
   } else {
     if(new Date(acc[isPresent].date) < new Date(elem.date)) acc[isPresent] = elem;
   }
  return acc;
},[]);

console.log(result);

2 Comments

Is it isPresent = data.findIndex(k=>k.website==elem.website) ?
@AshwanthMadhav No it will be acc which is accumulator of the reduce fn. where we will be checking if data is already there or not.
0

Try this- It also takes into consideration when the object is duplicate and dateTime are same/equal :

 var d = { "data" : [ 
{
    "position" : 0,
    "website" : "abc.com",
    "owned" : false,
    "date" : "2020-05-06",
    "dateTime" : "2020-05-06T00:00:00.000Z"
}, 
{
    "position" : 0,
    "website" : "qwe.com",
    "owned" : false,
    "date" : "2020-05-06",
    "dateTime" : "2020-05-06T00:00:00.000Z"
}, 
{
    "position" : 0,
    "website" : "xyz.agency",
    "owned" : false,
    "date" : "2020-05-06",
    "dateTime" : "2020-05-06T00:00:00.000Z"
}, 
{
    "position" : 1,
    "website" : "opq.com",
    "owned" : true,
    "date" : "2020-05-06",
    "dateTime" : "2020-05-06T00:00:00.000Z"
}
]

}

 var filtered = d.data.filter((el,idx)=> {
   let found = d.data.findIndex((e,i)=> e.website === el.website && idx !== i);

     return found === -1 ? el:Date.parse(el.dateTime) === 
          Date.parse((d.data[found]).dateTime)  && (found < idx) ? el: 
          Date.parse(el.dateTime) < 
          Date.parse((d.data[found]).dateTime) ? el: false
   });

console.log(filtered);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.