代码之家  ›  专栏  ›  技术社区  ›  Thomas

在F#中,当字符串具有一些轻标记属性时,如何按块分割字符串列表?

  •  0
  • Thomas  · 技术社区  · 5 年前

    我有一个工具,是使用一个电报聊天机器人与用户互动。

    电报限制了呼叫速率,所以我使用了一个定期刷新的队列系统。

    // flush the message queue
    let flushMessageQueue() =
        if not messageQueue.IsEmpty then       <- messageQueue is a ConcurrentQueue
    
            // get all the messages
            let messages =
                messageQueue
                |> Seq.unfold(fun q ->
                    match q.TryDequeue () with
                    | true, m -> Some (m, q)
                    | _ -> None)
    
            // put all the messages in a single string
            let messagesString = String.Join("\n", messages)
    
            // send the data
            client.SendTextMessageAsync(chatId, messagesString, ParseMode.Markdown)
            |> Async.AwaitTask
            |> Async.RunSynchronously
            |> ignore
    

    这是按固定间隔调用的,而写入是:

    // broadcast message
    let broadcastMessage message =
        messageQueue.Enqueue(message)
        printfn "%s" (message.Replace ("```", String.Empty))
    

    但随着信息变得越来越复杂,两个问题同时出现:

    • 一些行块被包装在``节之间
    • 在某些行中也有一些``节

    一些文本示例可能是:

    ```
    this is a group of lines
    with one, or many many lines
    ```
    and sometimes there are things ```like this``` as well
    

    还有。。。我发现电报也将消息大小限制为4kb

    • 我可以使用open/close ``来维护一个状态,并从队列中拉出,根据状态将每一行包装成三个回勾,然后推入另一个队列,该队列将用于生成4kb块。
    • 我可以不断地从重新格式化的队列中获取消息并聚合它们,直到达到4kb,或者在队列末尾循环。

    在F#有什么优雅的方法可以做到这一点吗? 我记得看到过一个片段,其中使用了一个collection函数来聚合数据,直到达到一定的大小,但它看起来非常低效,因为它正在收集line1、line1+line2、line1+line2+line3。。。然后挑一个大小合适的。

    0 回复  |  直到 5 年前
    推荐文章