Multiply each element of generic class

Viewed 94

I have a generic class, that contains a list of type T, and I have method 'concat' that concatenates two objects and return new one. I need to make it concat two lists, but if the type of list Int, Double or Float it should multiply each element of list on result of func

class Seq[T : Ordering] (initialElems: T*)(implicit toStr: ToStr[T]) {

  override def toString: String = toStr(fac(factors), elems: _*)

  val elems = initialElems.sorted

  def concat(a:Seq[T]) = new Seq(a.elems ++ this.elems:_*)

  val factors = ListBuffer[Int](1)

  def fac(xs: ListBuffer[Int]): Int = {
    var i=0
    var sum = 1
    while (i < xs.length) {
      sum *= xs(i)
      i += 1
    }
    sum
  }

  def multy(a: Int)(implicit ev: T <:< AnyVal): Unit = {
    factors += a
  }
}

trait ToStr[T] {
  def apply(fac: Int, elems: T*): String
}
object ToStr {
  implicit val int: ToStr[Int] =
    (fac, elems) => elems.map((i: Int) => fac * i).toString
  implicit val double: ToStr[Double] =
    (fac, elems) => elems.map((i: Double) => fac * i).toString
  implicit val float: ToStr[Float] =
    (fac, elems) => elems.map((i: Float) => fac * i).toString
  implicit val str: ToStr[String] = (_, elems) => elems.toString
}

For example I create two lists

val numbers1 = new Seq(1,5,4,2)  
val numbers2 = new Seq(7,8,11,17) 

than I add factors to

number1: numbers1.multy(5)
numbers1.multy(3) 

And factor to

number2: numbers2.multy(10)

And after I concat number = number1.concat(numbers2), I expect to get numbers which contains (1*3*5, 5*3*5, 4*3*5, 2*3*5, 7*10, 8*10, 11*10, 17*10) (And after sorting it will be) ->

(15, 30, 60, 70, 75, 80, 110, 170)

And if list of strings it shouldn't multiply and just concat. For example

strings1 = new Seq("b", "e", "f")
strings2 = new Seq("c", "a")
strings = strings1.concat(strings2)

strings will be ("a", "b", "c", "e", "f") How can I change method concat to work in such way?

1 Answers

I would try pattern matching with guard conditions, as an example:

def concat[A](a: Seq[A]) = {
    a match {
        case(h::_) if h.isInstanceOf[Int] => // do multiply and return as ....
        case(h::_) if h.isInstanceOf[String] => // do concat and return as ....
        case _ => throw new NoSuchElementException
    }
}
Related