openlang

Gleam 的列表能从最后一项开始反向索引吗?

我需要拆分含有不同数量 - 分隔符的字符串。我想取倒数第四项,并忽略拆分后片段数量不足的结果

 let segments = string.split("2-33-444-5555-66666-7777-8888", on: "-")
 let chosen = segments[-4] // <- This syntax is not valid.

这份指南中写道 (https://tour.gleam.run/everything/#basics-lists)。

计算列表长度,或取得列表开头以外位置的元素,开销都很大,所以人们很少这样做。在 Gleam 中,通过索引访问序列的算法并不常见,而在这些场景中,列表并不是合适的数据结构。

但它没有建议另一种数据结构。怎样才能从后往前取得拆分后的片段?

从英语翻译查看原文

后续讨论 2

顺着彼此的依据读下去
  1. 固定链接

    先把列表反转。

     let segments = list.reverse(segments)

    然后取第 4 个元素

     let chosen = case list.drop(segments, 3) {
       [fourth, ..] -> fourth
       [] -> ""
     }

    我还没在本机运行过,不过这样应该可以吧?

    更符合习惯的写法如下。

     pub fn fourth_from_tail(entries: String) -> Result(String, Nil) {
       case list.reverse(string.split(entries, on: "-")) {
         // Matches if there are at least 4 segments, binding the 4th from the end to `picked`
         [_, _, _, picked, ..] -> Ok(picked)
         // Discards strings with fewer than 4 segments
         _ -> Error(Nil) 
       }
     }
    从英语翻译查看原文
  2. 固定链接

    我找到了一种把 [-4] 这种简写语法封装到函数中的方法。

     fn item_from_back(entries: List(a), position: Int) -> Result(a, Nil) {
       let size = list.length(entries)
       case size >= position {
         True -> list.drop(entries, size - position) |> list.first
         False -> Error(Nil)
       }
     }
    
     let segments = string.split("2-33-444-5555-66666-7777-8888", on: "-")
     case item_from_back(segments, 4) {
         Ok(piece) -> io.println("piece: " <> piece)
         _ -> io.println("No piece found!")
    
     }
    从英语翻译查看原文

同一个问题的其他角度

  1. 在 Godot 3.3 的 GDScript 中怎样随机选择枚举项而不用逐项列出?

    这是我在 GDScript 中使用的枚举声明。 我想随机选择一个枚举变体,而不用列出所有可能的变体。这样以后增加变体时,就不必修改负责随机选择的代码。 我尝试过下面这种方法。 还有这一种。 两种都失败了。一个返回 Null,另一个报告 "Invali…

    回复 2最近活动 gdscript
  2. 空归约返回单位元

    对空向量做归约,APL 有答案。 每个原语都自带它的单位元。加法是 0,乘法和与是 1。⌈/⍬ 给出解释器里最小的负数。调用方不需要特殊处理,归约之前也不用检查长度。 dfn 就没有这种待遇。{⍺+⍵}/⍬ 在 Dyalog 里是 DOMAIN ER…

    回复 3最近活动 apl
  3. 我的大部分宏最后都变成了 const 和 static

    Nim 写宏太容易了,问题就出在这儿。 在动手写 macro 之前,先看看更便宜的工具。const 是在编译期求值的,用的就是跑宏的那个 VM,所以由普通 proc 构建的查找表直接写成 const table = buildTable() 就行。s…

    回复 3最近活动 nim