Scala:如何按值乘以列表列表

时间:2017-11-15 23:26:35

标签: scala list multiplying

正在研究Scala并使用列表列表。想要将数组乘以一个元素(例如,1)。

但是我收到以下错误:

  预期

标识符,但找到整数常量

当前代码:

def multiply[A](listOfLists:List[List[A]]):List[List[A]] =
if (listOfLists == Nil) Nil
else -1 * listOfLists.head :: multiply(listOfLists.tail) 
val tt = multiply[List[3,4,5,6];List[4,5,6,7,8]]
print(tt);;

2 个答案:

答案 0 :(得分:2)

您的代码存在一些问题:

  1. 通常,您无法对无约束的泛型类型执行算术运算;不知何故,你必须传达任何支持的算术运算。
  2. 乘以1通常无效。
  3. 如前所述,您不使用方括号声明List实例(它们用于声明泛型类型参数)。
  4. 您传递给multiply的参数是两个单独的列表(使用无效的分号分隔符而不是逗号),而不是列表列表。
  5. if子句中,返回值为Nil,与List[List[A]]的指定返回类型相匹配。但是,else子句正在尝试执行一个计算,该计算将List个实例(不是列表的内容)乘以Int。即使这是有道理的,结果类型显然不是List[List[A]]。 (这也使我很难准确理解你想要完成的是什么。)
  6. 以下是修正上述内容的代码版本,假设您尝试将内部列表的每个成员乘以特定因子:

    // Multiply every element in a list of lists by the specified factor, returning the
    // resulting list of lists.
    //
    // Should work for any primitive numeric type (Int, Double, etc.). For custom value types,
    // you will need to declare an `implicit val` of type Numeric[YourCustomType] with an
    // appropriate implementation of the `Numeric[T]` trait. If in scope, the appropriate
    // num value will be identified by the compiler and passed to the function automatically.
    def multiply[A](ll: List[List[A]], factor: A)(implicit num: Numeric[A]): List[List[A]] = {
    
      // Numeric[T] trait defines a times method that we use to perform the multiplication.
      ll.map(_.map(num.times(_, factor)))
    }
    
    // Sample use: Multiply every value in the list by 5.
    val tt = multiply(List(List(3, 4, 5, 6), List(4, 5, 6, 7, 8)), 5)
    println(tt)
    

    这应该导致以下输出:

    List(List(15, 20, 25, 30), List(20, 25, 30, 35, 40))
    

    但是,您可能只是想将列表中的所有值相乘。这实际上更直接一点(注意不同的返回类型):

    def multiply[A](ll: List[List[A]])(implicit num: Numeric[A]): A = ll.flatten.product
    
    // Sample use: Multiply all values in all lists together.
    val tt = multiply(List(List(3, 4, 5, 6), List(4, 5, 6, 7, 8)))
    println(tt)
    

    这应该导致以下输出:

    2419200
    

    我建议你阅读一本关于 Scala 的好书。这些例子中有很多相当复杂的东西,这里需要很长时间来解释它。一个好的开始将是由Odersky,Spoon& amp;的Scala编程,第三版。凡纳斯。这将涵盖List[A]mapflatten以及product函数参数和implicit声明等implicit val次操作。

答案 1 :(得分:1)

要使数字操作可用于键入A,您可以使用context boundAscala.math.Numeric关联,后者提供times和{{}等方法1}}在这个用例中进行必要的乘法运算:

fromInt

有关def multiply[A: Numeric](listOfLists: List[List[A]]): List[List[A]] = { val num = implicitly[Numeric[A]] import num._ if (listOfLists == Nil) Nil else listOfLists.head.map(times(_, fromInt(-1))) :: multiply(listOfLists.tail) } multiply( List(List(3, 4, 5, 6), List(4, 5, 6, 7, 8)) ) // res1: List[List[Int]] = List(List(-3, -4, -5, -6), List(-4, -5, -6, -7, -8)) multiply( List(List(3.0, 4.0), List(5.0, 6.0, 7.0)) ) // res2: List[List[Double]] = List(List(-3.0, -4.0), List(-5.0, -6.0, -7.0)) 的详细信息,请参阅相关的SO link