gpt4 book ai didi

arrays - 仅将函数应用于Scala中列表或数组中的一个元素

转载 作者:行者123 更新时间:2023-12-01 08:28:57 25 4
gpt4 key购买 nike

例如对于任何给定的列表或数组

val list = (1 to 3).toList
val array = (1 to 3).toArray

以及从集合类型映射到集合类型的给定函数,例如

def f(v: Int): Int = v + 10

如何将 f 应用于 listarray 的第 i 个元素,以便

list.myApply(f, ith = 2)
res: List(1,12,3)

还有

array.myApply(f, ith = 2)
res: Array(1,12,3)

最佳答案

tl;dr

import scala.collection.SeqLike
import scala.collection.generic.CanBuildFrom

implicit class Seq_[A, Repr,
S : ({type L[X] = X => SeqLike[A, Repr]})#L](seq: S) {

def myApply[B >: A, That](f: A => B, ith: Int)
(implicit bf: CanBuildFrom[Repr, B, That]): That =
seq.updated(ith - 1, f(seq(ith - 1)))
}

讨论

一个简单的近似:

implicit class Seq_[A](seq: Seq[A]) {
def myApply(f: A => A, ith: Int): Seq[A] =
seq.updated(ith - 1, f(seq(ith - 1)))
}

示例用法:

scala> (1 to 3).toList.myApply(_ + 10, ith = 2)
res: Seq[Int] = List(1, 12, 3)

尝试的实际解决方案:

implicit class Seq_[A, Repr <: SeqLike[A, Repr]](seq: Repr) {
def myApply[B >: A, That](f: A => B, ith: Int)
(implicit bf: CanBuildFrom[Repr, B, That]): That =
seq.updated(ith - 1, f(seq(ith - 1)))
}

不幸的是,隐式不起作用。我不知道为什么。

scala> Seq_[Int, List[Int]]((1 to 3).toList).myApply(_ + 10, ith = 2)
res: List[Int] = List(1, 12, 3)

scala> Seq_[Int, List[Int]]((1 to 3).toList).myApply(_.toString + "*", ith = 2)
res: List[Any] = List(1, 2*, 3)

编辑:修复它!

implicit class Seq_[A, Repr](seq: SeqLike[A, Repr]) {
def myApply[B >: A, That](f: A => B, ith: Int)
(implicit bf: CanBuildFrom[Repr, B, That]): That =
seq.updated(ith - 1, f(seq(ith - 1)))
}

例子:

scala> (1 to 3).toList.myApply(_ + 10, ith = 2)
res: List[Int] = List(1, 12, 3)

scala> (1 to 3).toVector.myApply(Math.pow(2, _), ith = 3)
res: scala.collection.immutable.Vector[AnyVal] = Vector(1, 2, 8.0)

但我刚刚意识到你也希望它适用于 Array,它不是 SeqLike,所以让我再想一想...

啊,Predef有一个从ArrayArrayOps的隐式转换,是SeqLike的子类型,所以我们只需要使用 View 绑定(bind)。

implicit class Seq_[A, Repr <% SeqLike[A, Repr]](seq: Repr) {
def myApply[B >: A, That](f: A => B, ith: Int)
(implicit bf: CanBuildFrom[Repr, B, That]): That =
seq.updated(ith - 1, f(seq(ith - 1)))
}

最后我们有了正确的行为:

scala> (1 to 3).toList.myApply(_ + 10, ith = 2)
res: List[Int] = List(1, 12, 3)

scala> (1 to 3).toArray.myApply(Math.pow(2, _), ith = 3)
res: Array[AnyVal] = Array(1, 2, 8.0)

再次编辑 - samthebest 通知我 View 边界已被弃用,因此使用 this guide我们可以用一个非常难看的上下文绑定(bind)来替换它。

implicit class Seq_[A, Repr, 
S : ({type L[X] = X => SeqLike[A, Repr]})#L](seq: S) {

def myApply[B >: A, That](f: A => B, ith: Int)
(implicit bf: CanBuildFrom[Repr, B, That]): That =
seq.updated(ith - 1, f(seq(ith - 1)))
}

关于arrays - 仅将函数应用于Scala中列表或数组中的一个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25800702/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com