小编Ste*_*lis的帖子

获取Scala Iterable的前n个元素的最简单方法

是否有一个简单而有效的解决方案来确定Scala Iterable的前n个元素?我的意思是

iter.toList.sortBy(_.myAttr).take(2)
Run Code Online (Sandbox Code Playgroud)

但是当只有前2名感兴趣时,无需对所有元素进行排序.理想情况下,我正在寻找类似的东西

iter.top(2, _.myAttr)
Run Code Online (Sandbox Code Playgroud)

另请参阅:使用Ordering的顶部元素的解决方案:在Scala中,如何使用List.min或List.max订购[T]并保持代码可读

更新:

谢谢大家的解决方案.最后,我采用了用户未知的原始解决方案并使用它Iterablepimp-my-library模式:

implicit def iterExt[A](iter: Iterable[A]) = new {
  def top[B](n: Int, f: A => B)(implicit ord: Ordering[B]): List[A] = {
    def updateSofar (sofar: List [A], el: A): List [A] = {
      //println (el + " - " + sofar)

      if (ord.compare(f(el), f(sofar.head)) > 0)
        (el :: sofar.tail).sortBy (f)
      else sofar
    }

    val (sofar, rest) = iter.splitAt(n)
    (sofar.toList.sortBy (f) /: rest) (updateSofar (_, _)).reverse
  }
} …
Run Code Online (Sandbox Code Playgroud)

algorithm scala

37
推荐指数
3
解决办法
2万
查看次数

如何压制"匹配并不详尽!" Scala中的警告

我怎么能压制"匹配并不详尽!" 以下Scala代码中的警告?

val l = "1" :: "2" :: Nil
l.sliding(2).foreach{case List(a,b) => }
Run Code Online (Sandbox Code Playgroud)

到目前为止,我发现的唯一解决方案是使用其他匹配语句包围模式匹配:

l.sliding(2).foreach{x => (x: @unchecked) match {case List(a,b) => }}
Run Code Online (Sandbox Code Playgroud)

然而,这使得代码不必要地复杂且难以理解.所以必须有一个更短,更可读的替代方案.有人知道吗?

编辑

我忘了提到我的列表l在我的程序中至少有2个元素.这就是为什么我可以安全地压制警告.

scala pattern-matching

21
推荐指数
2
解决办法
6287
查看次数

Scala中是否有FIFO流?

我正在寻找Scala中的FIFO流,即提供功能的东西

流应该是可关闭的,并且应该阻止访问下一个元素,直到添加元素或关闭流.

实际上我有点惊讶的是,集合库没有(似乎)包含这样的数据结构,因为IMO是一个非常经典的数据结构.

我的问题:

  • 1)我忽略了什么吗?是否已有提供此功能的课程?

  • 2)好的,如果它没有包含在集合库中,那么它可能只是现有集合类的一个简单组合.但是,我试图找到这个简单的代码,但对于这样一个简单的问题,我的实现看起来仍然非常复杂.这样的FifoStream有更简单的解决方案吗?

    class FifoStream[T] extends Closeable {
    
    val queue = new Queue[Option[T]]
    
    lazy val stream = nextStreamElem
    
    private def nextStreamElem: Stream[T] = next() match {
        case Some(elem) => Stream.cons(elem, nextStreamElem)
        case None       => Stream.empty
    }
    
    /** Returns next element in the queue (may wait for it to be inserted). */
    private def next() = {
        queue.synchronized {
            if (queue.isEmpty) queue.wait()
            queue.dequeue()
        }
    }
    
    /** Adds new elements to this stream. */
    def …
    Run Code Online (Sandbox Code Playgroud)

queue scala stream fifo

14
推荐指数
1
解决办法
5012
查看次数

检测Scala程序中函数更改的最佳实践?

我正在研究一种基于Scala的脚本语言(内部DSL),它允许用户在Scala脚本文件中定义多个数据转换函数.由于这些功能的应用可能需要几个小时,我想将结果缓存在数据库中.允许用户更改转换函数的定义以及添加新函数.但是,然后用户使用略微修改的脚本重新启动应用程序,我只想执行已更改或添加的那些功能.问题是如何检测这些变化?为简单起见,我们假设用户只能调整脚本文件,以便可以假定对此脚本中未定义的内容的任何引用都不会更改.

在这种情况下,检测此类用户定义函数的更改的最佳实践是什么?

到现在为止我虽然:

  • 解析脚本文件并根据函数定义的源代码计算指纹
  • 在运行时获取每个函数的字节码,并根据此数据构建指纹
  • 将函数应用于某些测试数据并计算结果上的指纹

然而,这三种方法都存在缺陷.

  • 为Scala编写解析器以提取函数定义可能是相当有用的,特别是如果您想要检测间接影响函数行为的更改(例如,如果您的函数调用脚本中定义的另一个(更改的)函数).
  • 字节码分析可能是另一种选择,但我从未使用过这些库.因此我不知道他们是否可以解决我的问题以及他们如何处理Java的动态绑定.
  • 具有示例数据的方法肯定是最简单的方法,但是具有如下缺点:如果针对我的测试数据返回相同的结果,则不同的用户定义的函数可能被意外地映射到相同的指纹.

有人有这些"解决方案"的经验或者可以建议我更好吗?

java scala bytecode

11
推荐指数
1
解决办法
188
查看次数

Scala元组的一般'map'功能?

我想使用返回类型R的单个函数映射Scala元组(或三元组......)的元素.结果应该是元组类型为R的元组(或三元组......).

好的,如果元组的元素来自同一类型,则映射不是问题:

scala> implicit def t2mapper[A](t: (A,A)) = new { def map[R](f: A => R) = (f(t._1),f(t._2)) }
t2mapper: [A](t: (A, A))java.lang.Object{def map[R](f: (A) => R): (R, R)}

scala> (1,2) map (_ + 1)
res0: (Int, Int) = (2,3)
Run Code Online (Sandbox Code Playgroud)

但是,是否也可以使这个解决方案通用,即以相同的方式映射包含不同类型元素的元组?

例:

class Super(i: Int)
object Sub1 extends Super(1)
object Sub2 extends Super(2)

(Sub1, Sub2) map (_.i)
Run Code Online (Sandbox Code Playgroud)

应该回来

(1,2): (Int, Int)
Run Code Online (Sandbox Code Playgroud)

但我找不到解决方案,以便映射函数确定Sub1和Sub2的超类型.我试图使用类型边界,但我的想法失败了:

scala> implicit def t2mapper[A,B](t: (A,B)) = new { def map[X >: A, X >: B, R](f: X => R) …
Run Code Online (Sandbox Code Playgroud)

scala tuples contravariance superclass

9
推荐指数
2
解决办法
4740
查看次数

代码格式:如何将多行代码与特殊字符对齐?

IDEA或其中一个插件是否能够将代码与特殊字符对齐?

我的意思是代码

Map(
  'name -> "Peter",
  'age -> 27,
  'company -> "Foobar"
)
Run Code Online (Sandbox Code Playgroud)

变成了

Map(
  'name    -> "Peter",
  'age     -> 27,
  'company -> "Foobar"
)
Run Code Online (Sandbox Code Playgroud)

例2:

execute("x", true, 27)
execute("foobar", false, 0)
Run Code Online (Sandbox Code Playgroud)

变成了

execute("x"     , true , 27)
execute("foobar", false, 0 )
Run Code Online (Sandbox Code Playgroud)

scala code-formatting intellij-idea

9
推荐指数
1
解决办法
1991
查看次数

在case类中重命名和覆盖equals方法

我想定义一个名称Ext,它将现有equals方法重命名为,equalsByAttributes并同时定义一个新equals方法.该特征用于扩展案例类.我目前的解决方案看起来有点hacky:

case class A(id: Int) extends Ext

trait Ext { p: Product =>
    // new implementation
    override def equals(obj: Any) = obj match {
        case that: AnyRef => this eq that
        case _ => false
    }

    // reimplementation of old equals implementation
    def equalsByAttributes(obj: Any) = obj match {
        case that: Product =>
            if (this.getClass.isAssignableFrom(that.getClass) || that.getClass.isAssignableFrom(this.getClass))
                p.productIterator.toList == that.productIterator.toList
            else
                false
        case _ => false
    }
}
Run Code Online (Sandbox Code Playgroud)

我不知道是否有引用一个直接的方式Aequals …

scala case-class

8
推荐指数
2
解决办法
8334
查看次数

如何在运行时确定Scala类的属性?

我想以编程方式在运行时确定Scala类的所有属性.例如,对于下面的Scala类,我想确定方法name1,name3,name4,和name5是为干将的性质A:

class A(val name1: String, private val name2: String) {
  val name3 = ""
  var name4 = ""
  def name5 = ""
  def name6() = ""
}
Run Code Online (Sandbox Code Playgroud)

大多数工作都可以使用Java的反射API完成.遗憾的是我没能检测之间的差异name5name6().因此,我开始使用ScalaSigParser下一个试验,但ScalaSig的标志对name5name6()是不幸的也是相同的.这是我的代码:

def gettersOf(clazz: Class[_]) = {
  for (ssig <- ScalaSigParser.parse(clazz))
  yield {
    ssig.symbols.toList.collect{
      case m: MethodSymbol => m
    }.filter(m => (m.symbolInfo.flags & 0xFFFFF) == 0x200)
  }
}

gettersOf(classOf[A]).get.foreach{m =>
  println(m.name + ": " + m) …
Run Code Online (Sandbox Code Playgroud)

reflection scala runtime introspection

3
推荐指数
1
解决办法
3574
查看次数