给定大量类型为T的元素(例如,向量或列表)和评估函数“ f”(例如,(T)=> Double)的集合(我们称其为“ a”),我想从“ a”中派生'结果集合'b'包含'a'的N个元素,这些元素导致f下的最大值。集合“ a”可能包含重复项。未排序。
也许暂时不考虑并行性(映射/归约等)的问题,用于编译结果集合“ b”的合适的Scala数据结构是什么?感谢您的任何指示/想法。
笔记:
(1)我想我的用例可以最简洁地表示为
val a = Vector( 9,2,6,1,7,5,2,6,9 ) // just an example
val f : (Int)=>Double = (n)=>n // evaluation function
val b = a.sortBy( f ).take( N ) // sort, then clip
Run Code Online (Sandbox Code Playgroud)
除了我不想对整个集合排序。
(2)一个选项可能是对'a'的迭代,该迭代用'manual'的大小范围填充TreeSet(拒绝任何比集合中最差的项目还差的东西,不要让集合增长到N以上)。但是,我想保留结果集中原始集中存在的重复项,因此这可能行不通。
(3)如果排序的多集是正确的数据结构,是否有此的Scala实现?还是二进制排序的Vector或Array(如果结果集相当小)?
给出了像多态的特征
trait Transform[T] { def apply( t: T ) : T }
Run Code Online (Sandbox Code Playgroud)
人们可能希望实现各种专门的实例,例如
case class Add[Double] extends Transform[Double] { def apply( t: Double ) ... }
case class Append[String] extends Transform[String] { def apply( t: String ) ... }
Run Code Online (Sandbox Code Playgroud)
现在,经常需要的变换也是身份变换.对于所有类型T,最好只使用一个单例实例,而不是为每个类型T专门设置标识.我的问题是:在Scala中实现此目的的最佳方法是什么?
这是我到目前为止所发现的:看看List [T]如何实现List.empty [T]和Nil,我尝试使用Nothing作为类型T.这似乎是有道理的,因为Nothing是所有其他类型的子类型:
object Identity extends Transform[Nothing] {
def apply( t: Nothing ) = t
}
Run Code Online (Sandbox Code Playgroud)
这似乎有效.但是,无论我在哪里,都希望按原样使用此实例,如下所示:
val array = Array[Transform[String]]( Transform.Identity )
Run Code Online (Sandbox Code Playgroud)
我得到编译器错误"类型不匹配;找到:Identity.type,required:Transform [String]".为了使用它,我必须明确地使用它:
... Identity.asInstanceOf[Transform[String]]
Run Code Online (Sandbox Code Playgroud)
我不确定这是最好还是"正确"的做法.谢谢你的建议.
我有一个问题的后续问题,有和没有参数的重载方法定义的存在导致编译错误,这已经在这里讨论:为什么这个引用不明确?
回顾一下:
trait A {
def foo( s: String ) : String
def foo : String = foo( "foo" )
}
object B extends A {
def foo( s: String ) : String = s
}
B.foo // won't compile
Run Code Online (Sandbox Code Playgroud)
导致错误消息:
error: ambiguous reference to overloaded function
both method foo in object B of type(s: String)String
and method foo in trait A of type => String
match expected type Unit
B.foo
Run Code Online (Sandbox Code Playgroud)
一个有效的解决方案是为编译器提供预期的类型,如下所示:
val s: String = B.foo
Run Code Online (Sandbox Code Playgroud)
不幸的是,人们可能并不总是想要引入额外的变量(例如在断言中).在上面引用的早期文章的答案中至少推荐两次的解决方案之一是使用空括号调用方法,如下所示:
B.foo() …Run Code Online (Sandbox Code Playgroud) 考虑这个片段定义模拟状态的特征,用户希望在某些派生类型中实现该特征.在特征上,一组实用程序方法应该能够提供具有实现类型的结果,类似于Scala库集合执行此操作的方式.为了实现这一点,我认为我需要使用实现类型来参数化特征,如下所示:
trait State[+This <: State[This]] {
def update : This // result has type of State's implementor
}
Run Code Online (Sandbox Code Playgroud)
现在我想定义一个多步更新方法,如下所示:
def update(steps: Int) : This
Run Code Online (Sandbox Code Playgroud)
当我尝试天真的方法时:
def update(steps: Int) : This =
(this /: (0 until steps))( (s,n) => s.update )
Run Code Online (Sandbox Code Playgroud)
编译器抱怨类型不匹配:
error: type mismatch;
found: State[This]
required: This
Run Code Online (Sandbox Code Playgroud)
这是有道理的,因为this在国家内部看到的是类型状态[This].要获得编译代码,似乎我必须进行显式转换:
def update(steps: Int) : This =
(this.asInstanceOf[This] /: (0 until steps))( (s,n) => s.update )
Run Code Online (Sandbox Code Playgroud)
有没有办法避免这种明确的演员,或者更普遍地以更好的方式实现预期的结果?谢谢.
我想定义一个带有一个显式参数和一个隐式参数的函数,如下所示:
def foo(a: Int)(implicit b: Int) : Int
Run Code Online (Sandbox Code Playgroud)
但作为一个类或对象,就像这样
object Foo extends ((Int,Int) => Int) {
def apply(a: Int)(implicit b: Int) : Int = { ... }
}
Run Code Online (Sandbox Code Playgroud)
这样可以像这样调用函数:
implicit val b = 2
val g = Foo(1)
Run Code Online (Sandbox Code Playgroud)
我没有得到哪个类Foo应该扩展的基础声明.如何才能做到这一点?
scala ×5
ambiguity ×1
casting ×1
fold ×1
function ×1
implicit ×1
nothing ×1
overloading ×1
polymorphism ×1
singleton ×1