首页 > 解决方案 > 如何将函数应用于字符串的所有字符

问题描述

Elm 中将函数应用于字符串的所有字符的最佳方法是什么?

例如,如果我想计算一个字符串的所有数字的总和,直到找到第一个“7”。这是我的解决方案。你能提出更好的建议吗?

sumString : Int -> String -> Int
sumString accumulator string =
    let
        firstChar =
            String.left 1 string

        rest =
            String.dropLeft 1 string
    in
    case firstChar of
        "" ->
            accumulator

        "7" ->
            accumulator

        _ ->
            sumString (accumulator + functionOnChar firstChar) rest


functionOnChar : String -> Int
functionOnChar string =
    Maybe.withDefault 0 (String.toInt string)

一些测试:

suite : Test
suite =
    describe "sumString function"
        [ test "12345" <|
            \_ ->
                Expect.equal 15 (sumString 0 "12345")
        , test "123456789" <|
            \_ ->
                Expect.equal 21 (sumString 0 "123456789")
        ]

标签: elm

解决方案


让我们将任务分成几个较小的任务。首先,我们要为字符串中的每个字符做一些事情。

  1. 而不是切割字符串,使用高阶函数

    sumUntil7 : String -> Int
    sumUntil7 string =
        String.foldl accumulateDigits 0 <| string
    

    accumulateDigits我们接下来要定义的函数在哪里。

  2. 然后我们用累加器函数将数字值相加:

    accumulateDigits : Char -> Int -> Int
    accumulateDigits char accumulator =
        accumulator + digitValue char
    

    digitValue我们接下来要定义的函数在哪里。

  3. 对于 Char 到 Int 的转换,我修改了您的方法以将 Char 作为参数:

    digitValue : Char -> Int
    digitValue char =
        Maybe.withDefault 0 <| String.toInt <| String.fromChar char
    
  4. 到目前为止,我们一直在将所有数字相加。现在我们将忽略从 first 开始的所有内容7,如果有的话:

    sumUntil7 : String -> Int
    sumUntil7 string =
        String.foldl accumulateDigits 0 <| portionBefore7 string
    

    portionBefore7我们接下来要定义的函数在哪里。

  5. 使用 String.indices 查找7字符串中的第一个:

    portionBefore7 : String -> String
    portionBefore7 string =
        String.left
            (Maybe.withDefault (String.length string) <|
                List.head <|
                    String.indices "7" string
            )
            string
    

通过将任务分成更小的子任务,并编写实用函数来完成它们,代码变得更具可读性。

完整代码在这里


推荐阅读