我有一个字符串长度列表,我想从它们中获取跨度索引。所以给定长度[23, 27, 47]
我想产生[(0, 23), (24, 27), (28, 47)]
。我怎样才能做到这一点?
到目前为止,这就是我所拥有的。我不确定自己走的路是否正确:
makeSpans :: [Int] -> [(Int, Int)]
makeSpans [x:y:xs] = [(x+1, y), makeSpans xs]
makeSpans [x:y] = (x+1, y)
makeSpans y = y
最佳答案
这是您想要的一个小例子:
> let list = ["abc", "abc", "abc"]
> import Control.Arrow
> fmap (second pred) $ zip <*> tail $ scanl (\acc x -> acc + length x) 0 list
> [(0,2),(3,5),(6,8)]
细分为:
scanl
列表,将每个单词的长度添加到累加器> zip <$> tail $ [0,3,6,9]
> [(0,3),(3,6),(6,9)]
second
映射到每对的第二个元素上,以固定对,使其不重叠(pred
等效于(-)1
)。 对我而言,这种解决方案比从头开始编写递归函数更容易构建。另外,它读起来就像管道,因此无需跟踪多个级别的间接和令人难以置信的递归。