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. Как случайно выбирать варианты enum в GDScript на Godot 3.3, не перечисляя их?

    Вот объявление enum, которое я использую в GDScript: Хочу случайно выбирать вариант enum, не перечисляя все возможные вариант…

    Ответы 2Последняя активность gdscript
  2. Свёртка пустого вектора возвращает нейтральный элемент

    Свёртка пустого вектора. APL отвечает. У каждой примитивной функции свой нейтральный элемент. Ноль для плюса. Единица для умн…

    Ответы 3Последняя активность apl
  3. Большинство моих макросов стали const и static

    Nim позволяет легко писать макросы. В этом и проблема. Прежде чем браться за macro, проверь инструменты подешевле. const вычи…

    Ответы 3Последняя активность nim