Skip to content

Instantly share code, notes, and snippets.

@raronson
Created January 16, 2013 22:39
Show Gist options
  • Save raronson/4551632 to your computer and use it in GitHub Desktop.
Save raronson/4551632 to your computer and use it in GitHub Desktop.
ordering of sets
implicit def Set2OrderingSet[A : Ordering]: Ordering[Set[A]] = {
new Ordering[Set[A]] {
def compare(s1: Set[A], s2: Set[A]): Int = {
for((x,y) <- s1.toList.sorted zip s2.toList.sorted) {
val c = implicitly[Ordering[A]].compare(x, y)
if(c != 0) return c
}
return s1.size - s2.size
}
}
}
@tonymorris
Copy link

object T {
  object Russell {
    implicit def Set2OrderingSet[A : Ordering]: Ordering[Set[A]] = { 
      new Ordering[Set[A]] {
        def compare(s1: Set[A], s2: Set[A]): Int = {
          for((x,y) <- s1.toList.sorted zip s2.toList.sorted) {
            val c = implicitly[Ordering[A]].compare(x, y)
            if(c != 0) return c
          }
          return implicitly[Ordering[Int]].compare(s1.size, s2.size)
        }
      }
    }
  }

  object WhyNot {
    implicit def Set2OrderingSet[A : Ordering]: Ordering[Set[A]] = { 
      new Ordering[Set[A]] {
        def compare(s1: Set[A], s2: Set[A]): Int =
          implicitly[Ordering[List[A]]].compare(s1.toList.sorted, s2.toList.sorted)        
      }
    }    

    implicit def List2OrderingSet[A : Ordering]: Ordering[List[A]] = { 
      new Ordering[List[A]] {
        // TODO convert to tail recursive
        def compare(s1: List[A], s2: List[A]): Int =
          (s1, s2) match {
            case (Nil, Nil) =>
              0
            // non-overlapping patterns FTW
            case (Nil, _::_) =>
              -1
            case (_::_, Nil) =>
              1
            case (h1::t1, h2::t2) => {
              val r = implicitly[Ordering[A]].compare(h1, h2)
              if(r == 0)
                implicitly[Ordering[List[A]]].compare(t1, t2)
              else
                r
            }
          }
      }
    }    
  }
}

@tonymorris
Copy link

object T {
  object Russell {
    implicit def Set2OrderingSet[A : Ordering]: Ordering[Set[A]] = { 
      new Ordering[Set[A]] {
        def compare(s1: Set[A], s2: Set[A]): Int = {
          for((x,y) <- s1.toList.sorted zip s2.toList.sorted) {
            val c = implicitly[Ordering[A]].compare(x, y)
            if(c != 0) return c
          }
          return implicitly[Ordering[Int]].compare(s1.size, s2.size)
        }
      }
    }
  }

  object WhyNot {
    implicit def Set2OrderingSet[A : Ordering]: Ordering[Set[A]] = { 
      new Ordering[Set[A]] {
        def compare(s1: Set[A], s2: Set[A]): Int =
          implicitly[Ordering[List[A]]].compare(s1.toList.sorted, s2.toList.sorted)        
      }
    }    

    implicit def List2OrderingSet[A : Ordering]: Ordering[List[A]] = { 
      new Ordering[List[A]] {
        def compare(s1: List[A], s2: List[A]): Int = {
          @annotation.tailrec
          def compareRec(r1: List[A], r2: List[A], n: Int): Int =
            (r1, r2) match {
              case (Nil, Nil) =>
                n
              case (_::_, Nil) =>
                1
              case (Nil, _::_) =>
                -1
              case (h1::t1, h2::t2) => {
                val r = implicitly[Ordering[A]].compare(h1, h2)
                if(r == 0)
                  compareRec(t1, t2, 0)
                else
                  r
              }
            }

          compareRec(s1, s2, 0)
        }
        /*
          (s1, s2) match {
            case (Nil, Nil) =>
              0
            // non-overlapping patterns FTW
            case (Nil, _::_) =>
              -1
            case (_::_, Nil) =>
              1
            case (h1::t1, h2::t2) => {
              val r = implicitly[Ordering[A]].compare(h1, h2)
              if(r == 0)
                implicitly[Ordering[List[A]]].compare(t1, t2)
              else
                r
            }
          }
          */
      }
    }    
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment