【问题标题】:F#: Writing a function that takes any kind of array as inputF#:编写一个将任何类型的数组作为输入的函数
【发布时间】:2015-04-21 11:30:59
【问题描述】:

我是编程新手,F# 是我的第一语言。

这是我的代码的一部分:

let splitArrayIntoGroups (inputArray: string[]) (groupSize: int) =
        let groups = new LinkedList<string[]>()
        let rec splitRecursively currentStartIndex currentEndIndex =
            groups.AddLast(inputArray.[currentStartIndex..currentEndIndex]) |> ignore
            let newEndIndex = Math.Min((inputArray.Length - 1), (currentEndIndex + groupSize))
            if newEndIndex <> currentEndIndex then
                splitRecursively (currentStartIndex + groupSize) newEndIndex
        splitRecursively 0 (groupSize - 1)
        groups

我希望这个函数能够接受任何类型的数组(包括我自己定义的类型)作为输入。我应该做出哪些改变?

【问题讨论】:

  • 我真的认为你需要阅读有关 F# 的书籍/教程,而不是这么快就来。

标签: arrays f#


【解决方案1】:

这已经被回答了,但是这里你有一个不使用链表而只是列表数组的实现

let rec split<'T> (input: 'T array) size =
    let rec loopOn (tail : 'T array) grouped =
        let lastIndex = Array.length tail - 1
        let endindx = min (size - 1) lastIndex
        let arrWrapper = (fun e -> [|e|])
        let newGroup = tail.[0..endindx] 
                        |> List.ofArray
                        |> arrWrapper
                        |> Array.append grouped

        match tail with
            | [||] -> newGroup 
                       |> Array.filter (fun e -> List.length e > 0)
            | _ -> loopOn tail.[endindx + 1..] newGroup

    let initialState = [|List.empty<'T>|]
    loopOn input initialState

因为这是通用实现,你可以用不同的类型调用它

type Custom = {Value : int} 

let r = split<int> [|1..1000|] 10
let r2 = split<float> [|1.0..1000.0|] 10

let r3 = split<Custom> [|for i in 1..1000 ->
                            {Value = i}|] 10

【讨论】:

    【解决方案2】:

    将函数签名中的string[] 替换为_[]

    【讨论】:

    • 还需要进行另一项更改。
    • 你的意思是省略链表中的冗余类型注释......但我认为,一般的想法至少会有所帮助......
    猜你喜欢
    • 2019-12-05
    • 2019-10-18
    • 1970-01-01
    • 1970-01-01
    • 2021-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多