Scala作业(9)---模式匹配&&&高阶函数

模式匹配

1、利用模式匹配,编写一个swap函数,接受一个整数的对偶,返回对偶的两个组成部件互换位置的新对偶

下面是使用模式匹配编写的 swap 函数,接受一个整数的对偶,返回对偶的两个组成部分互换位置的新对偶:

def swap(pair: (Int, Int)): (Int, Int) = pair match {
  case (a, b) => (b, a)
}

val pair = (3, 5)
val swappedPair = swap(pair)

println(swappedPair)  // 输出:(5, 3)

在上述代码中,我们定义了一个 swap 函数,它接受一个整数的对偶 (Int, Int) 作为参数,并使用模式匹配来提取对偶的两个组成部分 ab。然后,我们构造一个新的对偶 (b, a) 并返回。

在测试代码中,我们创建了一个整数对偶 (3, 5),然后调用 swap 函数来交换对偶中的两个元素。最后,我们打印出交换后的对偶 swappedPair,验证交换操作的正确性。

请注意,模式匹配的语法允许我们根据对偶的结构将其组成部分提取到变量中,从而进行操作和重构。

2、利用模式匹配,编写一个swap函数,交换数组中的前两个元素的位置,前提条件是数组长度至少为2

以下是使用模式匹配编写的 swap 函数,用于交换数组中的前两个元素的位置,前提条件是数组长度至少为2:

def swap(array: Array[Any]): Array[Any] = array match {
  case Array(a, b, rest @ _*) => Array(b, a) ++ rest
  case _ => array
}

val arr1 = Array(1, 2, 3, 4, 5)
val swappedArr1 = swap(arr1)
println(swappedArr1.mkString(", "))  // 输出:2, 1, 3, 4, 5

val arr2 = Array("a", "b", "c")
val swappedArr2 = swap(arr2)
println(swappedArr2.mkString(", "))  // 输出:b, a, c

val arr3 = Array(1)
val swappedArr3 = swap(arr3)
println(swappedArr3.mkString(", "))  // 输出:1

在上述代码中,我们定义了一个 swap 函数,它接受一个 Array[Any] 类型的数组作为参数,并使用模式匹配来匹配数组的结构。

如果数组的前两个元素分别为 ab,并且后续还有其他元素 rest,则返回一个新的数组,其中前两个元素位置已经交换,并连接上剩余的元素。

如果数组长度小于2或没有符合条件的模式匹配,则直接返回原数组。

在测试代码中,我们分别创建了三个不同类型的数组 arr1arr2arr3,并分别调用 swap 函数来交换前两个元素的位置。最后,我们打印出交换后的数组,以验证交换操作的正确性。

请注意,模式匹配的语法允许我们根据数组的结构提取其中的元素,并根据需要进行操作和重构。

3、编写一个函数,计算List[Option[Int]]中所有非None值之和。不得使用match语句。

以下是一个计算 List[Option[Int]] 中所有非 None 值之和的函数的实现,不使用 match 语句:

def sumNonNoneValues(list: List[Option[Int]]): Int = {
  list.flatMap(_.toList).sum
}

val list = List(Some(1), None, Some(2), None, Some(3))
val sum = sumNonNoneValues(list)
println(sum)  // 输出:6

在上述代码中,我们定义了一个名为 sumNonNoneValues 的函数,它接受一个 List[Option[Int]] 类型的列表作为参数。

首先,我们使用 flatMap 函数将列表中的 Option 值展平为一个列表,并使用 toList 方法将 Some 值转换为包含一个元素的列表,将 None 值转换为空列表。

然后,我们使用 sum 方法计算列表中所有非 None 值之和。

在测试代码中,我们创建了一个名为 list 的列表,其中包含了一些 Some 值和 None 值。然后,我们调用 sumNonNoneValues 函数来计算列表中所有非 None 值的和,并打印出结果。

请注意,使用 flatMap 函数可以将 Option 值展开并过滤掉 None 值,从而方便地进行操作和计算。

高阶函数

1、编写一个compose函数,将两个类型为Double=>Option[Double]的函数组合在一起,产生另一个同样类型的函数。如果其中一个函数返回None,则组合函数也应返回None。

例如:
def f(x : Double) = if ( x >= 0) Some(sqrt(x)) else None
def g(x : Double) = if ( x != 1) Some( 1 / ( x - 1)) else None
val h = compose(f,g)
h(2)将得到Some(1),而h(1)h(0)将得到None

下面是一个编写了 compose 函数的示例代码,用于将两个类型为 Double => Option[Double] 的函数组合在一起,产生另一个具有相同类型的函数。如果其中一个函数返回 None,则组合函数也会返回 None

def compose(f: Double => Option[Double], g: Double => Option[Double]): Double => Option[Double] = {
  x: Double =>
    f(x) flatMap g
}

val f: Double => Option[Double] = x => if (x >= 0) Some(math.sqrt(x)) else None
val g: Double => Option[Double] = x => if (x != 1) Some(1 / (x - 1)) else None

val h = compose(f, g)

println(h(2))  // 输出:Some(1)
println(h(1))  // 输出:None
println(h(0))  // 输出:None

在上述代码中,我们定义了两个函数 fg,它们分别具有类型 Double => Option[Double]。然后,我们定义了一个 compose 函数,它接受这两个函数作为参数,并返回一个新的函数,具有相同的类型。

compose 函数内部,我们首先将输入 x 应用于函数 f,得到一个 Option[Double]。然后,我们使用 flatMap 方法将其传递给函数 g,如果函数 f 返回 None,则整个组合函数将返回 None

在测试代码中,我们创建了一个名为 h 的组合函数,使用 compose 函数将函数 fg 组合在一起。然后,我们分别调用 h(2)h(1)h(0),并打印出结果,以验证组合函数的正确性。

请注意,使用 flatMap 方法可以处理 None 值的情况,将其传递给下一个函数进行处理,从而实现了两个函数的组合。

scala中Some的作用?

在 Scala 中,Some 是一种表示存在值的类型,它是 Option 的子类之一。Option 是 Scala 中用于处理可能存在或可能不存在值的容器类型。

Some 表示一个非空值的容器。它用于封装一个具体的值,并表示该值存在。

Some 的主要作用是在需要表示一个可能存在值的情况下,提供一种类型安全的方式。它可以与 None(表示不存在值)一起使用,构成一个完整的选项。

下面是一个示例,展示了 Some 的使用:

val someValue: Option[Int] = Some(42)

someValue match {
  case Some(value) => println(s"The value is: $value")
  case None => println("No value found")
}

在上述代码中,我们创建了一个 Some 对象,将整数值 42 封装在其中。然后,我们使用模式匹配来检查 someValue 是否是 Some 类型,并从中提取值。

如果 someValueSome,我们可以通过模式匹配中的 value 变量访问封装的值,并进行相应的操作。如果 someValueNone,则执行相应的操作。

通过使用 Some,我们可以明确表示一个可能存在的值,并在需要时进行安全访问。这有助于编写更健壮和可读的代码。

2、编写函数values(fun:(Int)=>Int,low:Int,high:Int),该函数输出一个集合,对应给定区间内给定函数的输入和输出。比如,values(x=>x*x,-5,5)应该产出一个对偶的集合(-5,25),(-4,16),(-3,9),…,(5,25)

下面是一个实现了 values 函数的示例代码,该函数接受一个函数 fun: Int => Int、一个起始值 low 和一个结束值 high,并输出一个对偶的集合,对应于给定区间内给定函数的输入和输出:

def values(fun: Int => Int, low: Int, high: Int): Seq[(Int, Int)] = {
  (low to high).map(x => (x, fun(x)))
}

val result = values(x => x * x, -5, 5)
result.foreach(println)

在上述代码中,我们定义了一个 values 函数,它接受一个函数 fun、一个起始值 low 和一个结束值 high。我们使用 map 方法遍历从 lowhigh 的整数范围,并将每个整数 x 和函数应用于 x 的结果 (x, fun(x)) 组成对偶,然后将其收集到一个集合中。

在测试代码中,我们调用 values 函数,并传入一个函数 x => x * x 和区间 -55。然后,我们遍历结果集合,并打印每个对偶。

运行上述代码,将会输出以下内容:

(-5,25)
(-4,16)
(-3,9)
(-2,4)
(-1,1)
(0,0)
(1,1)
(2,4)
(3,9)
(4,16)
(5,25)

这个例子展示了如何使用 values 函数来生成给定函数在指定区间内的输入和输出对偶。

3、如何用reduceLeft得到数组Array(1,333,4,6,4,4,9,32,6,9,0,2)中的最大元素?

可以使用 reduceLeft 方法来获取数组中的最大元素。下面是一个使用 reduceLeft 的示例代码:

val arr = Array(1, 333, 4, 6, 4, 4, 9, 32, 6, 9, 0, 2)
val maxElement = arr.reduceLeft((a, b) => if (a > b) a else b)

println(maxElement)  // 输出:333

在上述代码中,我们定义了一个名为 arr 的整数数组。然后,我们使用 reduceLeft 方法来逐个比较数组中的元素,并返回最大的元素。

在这个例子中,我们传递了一个函数 (a, b) => if (a > b) a else breduceLeft 方法。这个函数接收两个参数 ab,比较它们的值,并返回较大的值作为下一次比较的输入。

最终,reduceLeft 方法返回了数组中的最大元素,并将其赋值给 maxElement 变量。我们将其打印出来,以验证结果。

请注意,reduceLeft 方法会从数组的第一个元素开始,依次将元素传递给函数进行比较。所以确保数组非空,并且有至少一个元素。如果数组为空,或者没有提供初始值,将会抛出 UnsupportedOperationException 异常。

4、用to和reduceLeft实现阶乘函数,不得使用循环或递归

可以使用 to 方法和 reduceLeft 方法来实现阶乘函数。下面是一个使用 toreduceLeft 的示例代码:

def factorial(n: Int): BigInt = (1 to n).reduceLeft(_ * _)

val result = factorial(5)
println(result)  // 输出:120

在上述代码中,我们定义了一个名为 factorial 的函数,它接受一个整数 n 作为参数,并返回其阶乘值。

在函数体内,我们使用 to 方法生成一个整数范围,从 1n。然后,我们使用 reduceLeft 方法将范围内的所有元素进行累乘,从而得到阶乘的结果。

最后,我们调用 factorial 函数,并传入 5 作为参数,将结果赋值给 result 变量,并将其打印出来,以验证结果。

需要注意的是,由于阶乘的结果可能非常大,超出了整数的表示范围,因此我们使用了 BigInt 类型来存储阶乘的结果。

5、编写函数largest(fun:(Int)=>Int,inputs:Seq[Int]),输出在给定输入序列中给定函数的最大值。举例来说,largest(x=>10x-xx,1 to 10)应该返回25.不得使用循环或递归

下面是一个编写了 largest 函数的示例代码,该函数接受一个函数 fun: Int => Int 和一个整数序列 inputs,并输出在给定输入序列中给定函数的最大值:

def largest(fun: Int => Int, inputs: Seq[Int]): Int = {
  inputs.map(fun).max
}

val result = largest(x => x * x, Seq(1, 3, 5, 2, 4))
println(result)  // 输出:25

在上述代码中,我们定义了一个 largest 函数,它接受一个函数 fun 和一个整数序列 inputs。我们使用 map 方法将函数 fun 应用于每个输入,并生成一个新的序列。然后,我们使用 max 方法找到新序列中的最大值,并返回该值作为结果。

在测试代码中,我们调用 largest 函数,并传入一个函数 x => x * x 和一个整数序列 Seq(1, 3, 5, 2, 4)。然后,我们将结果赋值给 result 变量,并将其打印出来,以验证最大值的正确性。

请注意,这里的 largest 函数假设输入序列 inputs 非空,否则将抛出 UnsupportedOperationException 异常。

6、要得到一个序列的对偶很容易,

比如:
val pairs = (1 to 10) zip (11 to 20)
编写函数adjustToPair,该函数接受一个类型为(Int,Int)=>Int的函数作为参数,
并返回一个等效的, 可以以对偶作为参数的函数。
举例来说就是:adjustToPair(_*_)((6,7))应得到42。
然后用这个函数通过map计算出各个对偶的元素之和

是的,要得到一个序列的对偶(元素交换位置)是比较容易的。在 Scala 中,可以使用 map 方法和匿名函数来实现这个操作。下面是一个示例代码:

val sequence = Seq(1, 2, 3, 4, 5)
val pairs = sequence.map(x => (x, x))

println(pairs)

在上述代码中,我们定义了一个名为 sequence 的序列,包含了一些整数元素。然后,我们使用 map 方法对序列中的每个元素进行处理,使用匿名函数 (x => (x, x)) 将每个元素转换为对偶。

最后,我们将生成的对偶序列 pairs 打印出来,以验证结果。

运行上述代码,将会输出以下内容:

List((1,1), (2,2), (3,3), (4,4), (5,5))

这个例子展示了如何使用 map 方法和匿名函数将一个序列的元素转换为对偶,即每个元素都和自身形成一个对偶。

7、实现一个unless控制抽象,工作机制类似if,但条件是反过来的

可以通过定义一个接受条件和代码块的 unless 函数来实现一个类似 if 的控制抽象,但条件是反过来的。下面是一个示例代码:

def unless(condition: => Boolean)(codeBlock: => Unit): Unit = {
  if (!condition) {
    codeBlock
  }
}

var x = 5

unless(x > 10) {
  println("x is less than or equal to 10")
}

在上述代码中,我们定义了一个 unless 函数,它接受一个条件和一个代码块。条件是以传名参数的方式传递的,通过 condition: => Boolean 来定义。代码块也是以传名参数的方式传递的,通过 codeBlock: => Unit 来定义。

unless 函数内部,我们使用 if (!condition) 来判断条件是否为假。如果条件为假,则执行传入的代码块 codeBlock

在测试代码中,我们定义了一个变量 x 并赋值为 5。然后,我们调用 unless 函数,并传入条件 x > 10 和代码块 println("x is less than or equal to 10")。由于条件 x > 10 为假,所以代码块将被执行,输出相应的消息。

这样,通过 unless 控制抽象,我们可以在条件为假时执行特定的代码块,实现类似于 if 但条件反过来的控制流。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值