一个人滑动?

Dan*_*ral 13 collections functional-programming scala

不通过索引处理集合的优点之一是避免逐个错误.这肯定不是唯一的优势,但它是其中之一.

现在,我经常用sliding在斯卡拉一些算法,但我觉得它通常会导致非常相似的off-by-一个错误的东西,因为一个slidingm大小的集合中的元素n有大小n - m + 1的元素.或者,更简单的list sliding 2是,一个元素短于list.

我得到的感觉是,在这种模式中存在缺失的抽象,这将是一部分sliding,一部分更多 - 就像foldLeftreduceLeft.但是,我想不出那可能是什么.任何人都可以帮我找到启示吗?

UPDATE

由于人们不清楚我在说什么,让我们考虑一下这个案例.我想大写一个字符串.基本上,每个没有字母的字母都应该是大写字母,所有其他字母应该是小写字母.使用sliding,我必须特殊情况下的第一个或最后一个字母.例如:

def capitalize(s: String) = s(0).toUpper +: s.toSeq.sliding(2).map {
  case Seq(c1, c2) if c2.isLetter => if (c1.isLetter) c2.toLower else c2.toUpper
  case Seq(_, x) => x
}.mkString
Run Code Online (Sandbox Code Playgroud)

Deb*_*ski 6

我把欧文的答案作为灵感.

如果要将简单diff()应用于列表,可以将其视为等效于以下矩阵乘法.

a = (0 1 4 3).T

M = ( 1 -1  0  0)
    ( 0  1 -1  0)
    ( 0  0  1 -1)

diff(a) = M * a = (1 3 1).T
Run Code Online (Sandbox Code Playgroud)

如果我们替换加法和乘法(如果我们对矩阵M中的数字进行推广),我们现在可以使用相同的方案进行一般列表操作.

因此,使用plus作为列表追加操作(flatten后面 - 或简单地collect操作),并且乘法等价物是Some(_)或者None,窗口大小为2的幻灯片变为:

M = (Some(_) Some(_) None None)
    (None Some(_) Some(_) None)
    (None None Some(_) Some(_))

slide(a) = M “*” a = ((0 1) (1 4) (4 3)).T
Run Code Online (Sandbox Code Playgroud)

不确定,如果这是你正在寻找的那种抽象,但它将是一类改变项目数量的操作的概括.

diff或者对于长度为n的输入slide的阶数m的操作将需要使用大小为n-m + 1×n的矩阵.


编辑:一个解决方案可能是转换List[A]List[Some[A]]然后添加或附加(slideLeftslideRight)这些None.这样你就可以处理方法中的所有魔法map.

list.slideLeft(2) {
  case Seq(Some(c1), Some(c2)) if c2.isLetter => if (c1.isLetter) c2.toLower else c2.toUpper
  case Seq(_, Some(x)) => x
}
Run Code Online (Sandbox Code Playgroud)


Owe*_*wen 2

我在 python/R/Matlab 中一直遇到这个问题,你 diff() 一个向量,然后无法将它与原始向量对齐!这是非常令人沮丧的。

我认为真正缺少的是向量仅包含变量,并假设您(程序员)正在跟踪变量,即集合范围的维度。

我认为解决这个问题的方法是让语言在某种程度上跟踪自变量;也许通过类型静态地进行,或者通过将它们与向量一起存储来动态地进行。然后它可以检查独立的轴,确保它们对齐,或者,我不知道这是否可能,将事物打乱以使它们对齐。

这是迄今为止我想到的最好的。

编辑

另一种思考方式是,为什么你的收藏有顺序?为什么它不只是一个集合?顺序是有意义的,但集合并没有跟踪它——它基本上使用顺序位置(其信息量与数字索引一样)来代表真正的含义。

编辑

另一个结果是像这样的变换sliding实际上代表了两种变换,一种用于因变量,另一种用于它们的轴。