Levijatanu
Levijatanu

Reputation: 418

Remove duplicates from list of DateTime objects only by Date component

What is preferred way to remove duplicates from list Joda DateTime objects but only by date component (no time component )

var dates = List[DateTime]()

dates = dates ::: List(new DateTime(2015, 1, 1, 0, 0, 0, 0))
dates = dates ::: List(new DateTime(2011, 1, 1, 0, 0, 0, 1))
dates = dates ::: List(new DateTime(2011, 1, 1, 0, 0, 0, 0)) // different millisOfSecond

println(dates.distinct)

Results in

List(2015-01-01T00:00:00.000+01:00,
     2011-01-01T00:00:00.001+01:00,
     2011-01-01T00:00:00.000+01:00)

Upvotes: 1

Views: 699

Answers (3)

Levijatanu
Levijatanu

Reputation: 418

I did it this way:

def orderAndDeleteDuplicatesList(unorderedList: List[DateTime]): List[DateTime] ={


if(unorderedList == Nil || unorderedList.isEmpty) return unorderedList


//order by millis
val sortedList : List[DateTime] =  unorderedList.sortBy(_.getMillis)
var previousElement :Option[DateTime] = None
var purgedAndSortedList = List[DateTime]() //return list
sortedList.foreach ( element  => {

  //Ako trenutni element nije jednak prethodnom ili je prethodni prazan dodaj ga na listu
  if(previousElement.isEmpty || dtc.compare(previousElement.get, element) != 0 ){
    purgedAndSortedList = purgedAndSortedList ::: List(element)
  }

  previousElement = Option(element)

})

purgedAndSortedList
}

DateComparator:

import org.joda.time.{DateTime, DateTimeComparator}

private val dtc: DateTimeComparator = DateTimeComparator.getDateOnlyInstance

Upvotes: 0

Nagarjuna Pamu
Nagarjuna Pamu

Reputation: 14825

Write a wrapper case class and override the equals method to do equality based on date component.

case class DateTimeWrapper(dt: DateTime) {
  override def equals(obj: scala.Any): Boolean = obj match {
    case x: DateTimeWrapper => x.dt.getDayOfMonth == this.dt.getDayOfMonth
    case _ => false
  }
}

Here is the distinct method which uses Set to pick non duplicate elements

def distincts(list: List[DateTime]): List[DateTime] = {
  def helper(set: Set[DateTimeWrapper], list: List[DateTimeWrapper]) = list match {
    case Nil => set
    case x :: xs => if (set contains x) set else set + x
  }
  helper(Set.empty[DateTimeWrapper], list.map(DateTimeWrapper)).toList.map(_.dt)
}

Write an Implicit to make the API look better

implicit class ListUtils(list: List[DateTime]) {
  def distinctElems = distincts(list)
}

Usage:

val dates = List(
  new DateTime(2015, 1, 1, 0, 0, 0, 0),
  new DateTime(2011, 1, 1, 0, 0, 0, 1),
  new DateTime(2011, 1, 1, 0, 0, 0, 0)
)

println(dates.distinctElems.length)

Upvotes: 2

Scott Shipp
Scott Shipp

Reputation: 2321

Use the JodaTime DateTimeComparator.getDateOnlyInstance() method. This gives you a DateTimeComparator that compares only by date. See the API at http://www.joda.org/joda-time/apidocs/index.html?org/joda/time/DateTimeComparator.html

Upvotes: 1

Related Questions