diff --git a/demo-scala/src/UnweightedStream.scala b/demo-scala/src/UnweightedStream.scala index a7841f0..8497a49 100644 --- a/demo-scala/src/UnweightedStream.scala +++ b/demo-scala/src/UnweightedStream.scala @@ -1,25 +1,44 @@ import java.util.Random +import SamplingIterator._ import gr.james.sampling.{RandomSampling, WatermanSampling} import scala.collection.JavaConverters._ /** - * Unweighted random sampling using functional constructs. + * Extension of the [[Iterator]] with the sample method. + * + * @param it the source iterator + * @tparam T the element type */ -object UnweightedStream extends App { - val sample = (0 until 20) - .foldLeft(construct[Int](5, new Random()))(foldOperation) - .sample().asScala.toList - - def construct[T](sample: Int, random: Random): RandomSampling[T] = - new WatermanSampling[T](sample, random) - - def foldOperation[T] = +class SamplingIterator[T](val it: Iterator[T]) { + private val foldOperation = (rs: RandomSampling[T], i: T) => { rs.feed(i) rs } + /** + * Samples this iterator using the provided algorithm. + * + * @param rs the sampling algorithm + * @return a [[List]] containing the sampled elements + */ + def sample(rs: RandomSampling[T]): List[T] = it.foldLeft(rs)(foldOperation).sample().asScala.toList +} + +/** + * The [[SamplingIterator]] companion object with the iteratorToSamplingIterator implicit conversion. + */ +object SamplingIterator { + implicit def iteratorToSamplingIterator[T](s: Iterator[T]): SamplingIterator[T] = + new SamplingIterator(s) +} + +/** + * Unweighted random sampling using functional constructs. + */ +object UnweightedStream extends App { + val sample = (0 until 20).iterator.sample(new WatermanSampling[Int](5, new Random())) println(sample) } diff --git a/demo-scala/src/WeightedStream.scala b/demo-scala/src/WeightedStream.scala index 98a7d0a..1352058 100644 --- a/demo-scala/src/WeightedStream.scala +++ b/demo-scala/src/WeightedStream.scala @@ -1,33 +1,52 @@ import java.util.Random +import WeightedSamplingIterator._ import gr.james.sampling.{ChaoSampling, WeightedRandomSampling} import scala.collection.JavaConverters._ +/** + * Extension of the [[Iterator]] with the sample method. + * + * @param it the source iterator + * @tparam T the element type + */ +class WeightedSamplingIterator[T](val it: Iterator[(T, Double)]) { + private val foldOperation = + (rs: WeightedRandomSampling[T], i: (T, Double)) => { + rs.feed(i._1, i._2) + rs + } + + /** + * Samples this iterator using the provided algorithm. + * + * @param wrs the sampling algorithm + * @return a [[List]] containing the sampled elements + */ + def sample(wrs: WeightedRandomSampling[T]): List[T] = it.foldLeft(wrs)(foldOperation).sample().asScala.toList +} + +/** + * The [[WeightedSamplingIterator]] companion object with the iteratorToWeightedSamplingIterator implicit + * conversion. + */ +object WeightedSamplingIterator { + implicit def iteratorToWeightedSamplingIterator[T](s: Iterator[(T, Double)]): WeightedSamplingIterator[T] = + new WeightedSamplingIterator(s) +} + /** * Weighted random sampling using functional constructs. */ object WeightedStream extends App { - val map = Map( + val sample = Map( "collection" -> 1.0, "algorithms" -> 2.0, "java" -> 2.0, "random" -> 3.0, "sampling" -> 4.0, "reservoir" -> 5.0 - ) - val sample = map - .foldLeft(construct[String](2, new Random()))(foldOperation) - .sample().asScala.toList - - def construct[T](sample: Int, random: Random): WeightedRandomSampling[T] = - new ChaoSampling[T](sample, random) - - def foldOperation[T] = - (wrs: WeightedRandomSampling[T], i: (T, Double)) => { - wrs.feed(i._1, i._2) - wrs - } - + ).iterator.sample(new ChaoSampling[String](2, new Random)) println(sample) }