仅在斯卡拉列表或数组应用功能的一个元素 [英] Apply function to one element only in list or array in Scala
问题描述
对于任何给定列表或数组,例如
VAL名单=(1〜3).toList
VAL阵列=(1〜3).toArray
和给定函数,从和到集合类型映射,比如
DEF F(V:智力):INT = V + 10
如何˚F
适用于列表
或阵列$的第i个元素C $ C>,以便
list.myApply(F,第i = 2)
RES:列表(1,12,3)
和也
array.myApply(F,第i = 2)
RES:阵列(1,12,3)
TL;博士
进口scala.collection.SeqLike
进口scala.collection.generic.CanBuildFrom隐类Seq_ [A,再版,
小号:({L型[X] = X => SeqLike [A,再版]})#L](序列:S){ DEF myApply [B计算值:A,这(F:A => B,第i:智力)
(隐式BF:CanBuildFrom [再版,B,即]):那=
seq.updated(第i - 1,F(序列(第i - 1)))
}
讨论
一个幼稚的近似:
隐类Seq_ [A](序列:序列[A]){
高清myApply(F:A =>在第i:智力):序号[A] =
seq.updated(第i - 1,F(序列(第i - 1)))
}
实例:
斯卡拉> (1至3).toList.myApply(_ + 10,第i = 2)
RES:序号[INT] =名单(1,12,3)
尝试实际的解决方案:
隐类Seq_ [A,再版&LT ;: SeqLike [A,再版](SEQ:再版){
DEF myApply [B计算值:A,这(F:A => B,第i:智力)
(隐式BF:CanBuildFrom [再版,B,即]):那=
seq.updated(第i - 1,F(序列(第i - 1)))
}
不幸的是,隐式不起作用。我不知道为什么。
斯卡拉> Seq_ [诠释,列表[INT]]((1〜3).toList).myApply(_ + 10,第i = 2)
RES:列表[INT] =名单(1,12,3)斯卡拉> Seq_ [诠释,列表[INT]]((1〜3).toList).myApply(_。的toString +*,第i = 2)
RES:列表[任何] =名单(1,2 *,3)
编辑:固定它
隐类Seq_ [A,再版](SEQ:SeqLike [A,再版]){
DEF myApply [B计算值:A,这(F:A => B,第i:智力)
(隐式BF:CanBuildFrom [再版,B,即]):那=
seq.updated(第i - 1,F(序列(第i - 1)))
}
例如:
斯卡拉> (1至3).toList.myApply(_ + 10,第i = 2)
RES:列表[INT] =名单(1,12,3)斯卡拉> (1至3).toVector.myApply(Math.pow(2,_)第i = 3)
水库:scala.collection.immutable.Vector [AnyVal] =矢量(1,2,8.0)
但我只是意识到你还希望它为阵列
,这是不行的 SeqLike
,所以让我认为,一些更多...
啊, preDEF
已经从阵列
到 ArrayOps <隐式转换/ code>,这是
SeqLike
,所以我们只需要使用绑定的视图。
隐类Seq_ [A,再版&LT;%SeqLike [A,再版](SEQ:再版){
DEF myApply [B计算值:A,这(F:A =&GT; B,第i:智力)
(隐式BF:CanBuildFrom [再版,B,即]):那=
seq.updated(第i - 1,F(序列(第i - 1)))
}
最后,我们有正确的行为:
斯卡拉&GT; (1至3).toList.myApply(_ + 10,第i = 2)
RES:列表[INT] =名单(1,12,3)斯卡拉&GT; (1至3).toArray.myApply(Math.pow(2,_)第i = 3)
RES:数组[AnyVal] =阵列(1,2,8.0)
再修改 - samthebest告诉我,鉴于边界是pcated德$ P $,所以使用的本指南我们可以非常难看方面取代它的约束。
隐类Seq_ [A,再版,
小号:({L型[X] = X =&GT; SeqLike [A,再版]})#L](序列:S){ DEF myApply [B计算值:A,这(F:A =&GT; B,第i:智力)
(隐式BF:CanBuildFrom [再版,B,即]):那=
seq.updated(第i - 1,F(序列(第i - 1)))
}
For any given list or array, for instance
val list = (1 to 3).toList
val array = (1 to 3).toArray
and a given function that maps from and onto the collection type, for instance
def f(v: Int): Int = v + 10
how to apply f
to the ith element of list
or array
so that
list.myApply(f, ith = 2)
res: List(1,12,3)
and also
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)))
}
Discussion
A naive approximation:
implicit class Seq_[A](seq: Seq[A]) {
def myApply(f: A => A, ith: Int): Seq[A] =
seq.updated(ith - 1, f(seq(ith - 1)))
}
Example usage:
scala> (1 to 3).toList.myApply(_ + 10, ith = 2)
res: Seq[Int] = List(1, 12, 3)
Attempted actual solution:
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)))
}
Unfortunately, the implicit doesn't work. I'm not sure why.
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)
Edit: Fixed it!
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)))
}
Example:
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)
But I just realized you also wanted it to work for Array
, which isn't SeqLike
, so let me think some more...
Ah, Predef
has an implicit conversion from Array
to ArrayOps
, which is a subtype of SeqLike
, so we just need to use a view bound.
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)))
}
And finally we have the right behavior:
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)
Edit again - samthebest informs me that view bounds are deprecated, so using this guide we can replace it with a very ugly-looking context bound.
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)))
}
这篇关于仅在斯卡拉列表或数组应用功能的一个元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!