使用zipWithIndex的F#版Scala代码

时间:2014-10-24 12:58:34

标签: scala f#

这个Scala代码(我有点简化,所以我可能犯了一个错误)将一系列换行符分隔的输入行转换为这些行中非空格字符的坐标列表。下面是我将其转换为F#的失败尝试。

第一个坐标是行内字符的索引,第二个坐标是字符串中行的坐标。

F#似乎没有zipWithIndex的等价物(虽然它确实有一个提供索引的map重载),并且序列表达式的语法与Scala的生成器表达式的语法完全不同,我正在努力写F#等价物。

Scala代码:

val input = "X \n X"

def charCoors(input: String) = for {
    (xs, y) <- input.split('\n').map(_.zipWithIndex).zipWithIndex.iterator
    (c, x) <- xs.iterator
    if c != ' '
  } yield Coord(x, y)

我破碎的F#尝试:

let splitLines (s:string) = 
    List.ofSeq(s.Split([|'\n'|]))

let input = "X \n X"

let charCoords input =
    let lines = splitLines input
    seq {
        for (y, line) in List.map (fun y line -> (y, line)) lines do
            yield! for (x, character) in List.map (fun x character -> (x, character)) do
                if char != ' ' then
                    yield (x, y)
    }

1 个答案:

答案 0 :(得分:2)

我认为你几乎拥有它 - 你必须使用List.mapiSeq.mapi作为行(字符串是IEnumerable<char>但不是列表):

let charCoords input =
    let lines = splitLines input
    seq {
        for (y, line) in List.mapi (fun y line -> (y, line)) lines do
        for (x, character) in Seq.mapi (fun x character -> (x, character)) 
                                       line do
        if character <> ' ' then yield (x, y)
    }

请注意,这会编译并运行,但我不知道id是否符合您的要求:

> charCoords input;;

val it : seq<int * int> = seq [(0, 0); (1, 1)]