whiteBear22
whiteBear22

Reputation: 407

Angular 9 - Remove duplicates from array of objects

I have a problem with constructing filter data pipe. I would like to pass data with removed duplicates from my object.

This is my ngFor:

<ng-container *ngFor="let message of messages | filterDates">

I would like to pass my messages array through this pipe, to remove duplicate dates from each object. Each object in my array has

'timestamp': 1590064423327

some of objects has the same timestamp, and some of them not. I would like to set timestamp to null in those objects, if previous object from array has the same timestamp value. If previous has different timestamp value, I would like to pass timestamp as it is in current object.

To better understand, the example is: I'm receiving messages from my API with timestamps. I would like to show date for only first message, because next messages are from the same day, so there is no need to show date for those messages. If next messages are not from the same day, I would like to show only for the first message date value from next timestamp. It is for grouping messages by date.

I have prepared pipe for this, but unfortunately, I'm not sure what to do in this pipe to achieve this specific goal. I'm pretty sure, I should use Lodash, but I don't exactly know, which operator should I use. Thank you in advance for any help.

This is the problem I have from @Yogesh Developer answer:

enter image description here

I think problem here is, it's pushing to array element with null, then it compares next item with null timestamp. I forgot to mention, that I have to compare timestamps in formatted date way, because timestamps are with seconds so they will always be different. This is how I compare formatted dates with momentjs:

if (index > 0 && (moment(message.timestamp).format('DD/MM/YYYY') == moment(messages[index - 1].timestamp).format('DD/MM/YYYY'))) {
        message.timestamp = null
      }
      finalMessages.push(message)

Upvotes: 0

Views: 3202

Answers (3)

Rafał Gołubowicz
Rafał Gołubowicz

Reputation: 660

Should works fine

let finalMessages = [];
let prevTimestamp = null;
messages.forEach((message, index) => {
  if (moment(message.timestamp).isSame(moment(prevTimestamp), 'days')) {
    message.timestamp = null
  } else {
    prevTimestamp = message.timestamp
  }
  finalMessages.push(message)
})

Upvotes: 1

Rick
Rick

Reputation: 1870

the simple solution is to create an array of displayMessages in your javascript, then use displayMessages in your NgFor loop.

let displayMessages = [];
let timeStampHash = {};
messages.forEach(message) => {
  if (!timeStampHash[message.timestamp]) {
    timeStampHash[message.timestamp] = true;
    displayMessages.push(message);
  }
})
this.displayMessages = displayMessages;

Upvotes: 0

Yogesh Aggarwal
Yogesh Aggarwal

Reputation: 1115

You can do something like this in your filterDate pipe:

let finalMessages = []
messages.forEach((message, index) => {
  if (index > 0 && (message.timestamp == messages[index - 1])) {
    message.timestamp = null
  }
  finalMessages.push(message)
})

Upvotes: 0

Related Questions