Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package org.specs2
package collection
import scala.collection.{GenSeq, GenIterable}
import scalaz._
importGenerator._
import std.iterable._
importSeqx._
/**
* This trait provides additional methods on Iterable.
*
* It is made public so that users can reuse the sameElementsAs method
*/traitIterablex{
/**
* implicit definition to transform an Iterable to an ExtendedIterable
*/implicitdefextendIterable[T](xs : GenIterable[T]): ExtendedIterable[T] = newExtendedIterable(xs)
/**
* Additional methods for Iterable objects
*/classExtendedIterable[T](xs: GenIterable[T]) {
/**
* @return true if the 2 iterables contain the same elements, in the same order,
* according to a function f
*/defisSimilar[S >: T](that: GenIterable[S], f: Function2[T, S, Boolean]): Boolean = {
val it1 = xs.iterator
val it2 = that.iterator
var res = truewhile (res && it1.hasNext && it2.hasNext) {
res = f(it1.next, it2.next)
}
!it1.hasNext && !it2.hasNext && res
}
/**
* @return true if the 2 iterables contain the same elements recursively, in any order
*/defsameElementsAs(that: GenIterable[T]): Boolean = sameElementsAs(that, (x, y) => x == y)
/**
* This recursive function is not really well-formed (the `asInstanceOf` should be ample proof).
* It only works if T <===> Seq[T]
*
* This is the case for NodeFunctions.isEqualIgnoringSpace where it is used to check if 2 xml NodeSeqs have the same
* nodes regardless of whitespace
*
* @return true if the 2 iterables contain the same elements (according to a comparison function f) recursively, in any order
*/defsameElementsAs(that: GenIterable[T], f: (T, T) => Boolean): Boolean = {
defisNotItsOwnIterable(a: GenIterable[_]) = a.isEmpty || a.iterator.next != a
defmatchTwo(x: T, y: T): Boolean = {
(x, y) match {
case (a: GenIterable[_], b: GenIterable[_]) if isNotItsOwnIterable(a) =>
x.asInstanceOf[GenIterable[T]].sameElementsAs(y.asInstanceOf[GenIterable[T]], f)
case _ => f(x, y)
}
}
val ita = xs.iterator.toList
val itb = that.iterator.toList
(ita, itb) match {
case (Nil, Nil) => truecase (a: GenIterable[_], b: GenIterable[_]) => {
(a.headOption.isDefined && b.headOption.isDefined) && {
val (x, y, resta, restb) = (a.head, b.head, a.drop(1), b.drop(1))
matchTwo(x, y) && resta.sameElementsAs(restb, f) ||
resta.exists(matchTwo(_, y)) && restb.exists(matchTwo(x, _)) &&
resta.removeFirst(matchTwo(_, y)).sameElementsAs(restb.removeFirst(matchTwo(x, _)), f)
}
}
case _ => ita == itb
}
}
/**
* @return true if the second iterable elements are contained in the first, in order
*/defcontainsInOrder(l: T*): Boolean = {
val firstList = xs.toList
val secondList = l.toList
(firstList, secondList) match {
case (_, Nil) => truecase (Nil, _) => falsecase (a :: Nil, b :: Nil) => a == b
case (a :: firstRest, b :: secondRest) => {
if (a != b)
firstRest.containsInOrder(secondList:_*)
else
firstRest.containsInOrder(secondRest:_*)
}
}
}
/**
* @return the representation of the elements of the iterable using the toString method recursively
*/deftoDeepString: String = {
if (xs.nonEmpty && xs == xs.iterator.next)
xs.toString
else"[" + xs.toList.map {
case i: GenIterable[_] => i.toDeepString
case x => x.toString
}.mkString(", ") + "]"
}
/** map the first element with a function */defmapFirst(f: T => T): GenSeq[T] = (xs.take(1).map(f) ++ xs.drop(1)).toSeq
/** map the last element with a function */defmapLast(f: T => T): Seq[T] = (xs.seq.dropRight(1) ++ xs.seq.takeRight(1).map(f)).toSeq
/** reduce a list from left to right */defreduceWith[S](reducer: Reducer[T, S]) = FoldlGenerator[Iterable].reduce(reducer, xs.seq)
/** @return a sequence rotated of a number of elements */defrotate(n: Int) = xs.slice(n, xs.size) ++ xs.slice(0, n)
/** @return a randomly mixed sequence */defscramble: Seq[T] = scramble(new scala.util.Random)
/** @return a randomly mixed sequence */defscramble(random: scala.util.Random): Seq[T] =
// rotate arbitrarily the sequence first then sort randomly
xs.rotate(random.nextInt(xs.size+1)).seq.toSeq.sortWith((_,_) => random.nextInt(2) > 0)
}
}
objectIterablexextendsIterablex