#Is there a built-in function to search a string for the starting index of a given substring?
1 messages · Page 1 of 1 (latest)
no, doesn't look like it
It is relatively easy to write one:
pub fn index_of(haystack: String, needle: String) -> Int {
let needle_graphemes = string.to_graphemes(needle)
let needle_length = list.length(needle_graphemes)
haystack
|> string.to_graphemes
|> list.window(needle_length)
|> list.index_fold(from: -1, with: fn(acc, item, index) {
case item == needle_graphemes {
True -> index
False -> acc
}
})
}
Altho it's good to note, indexing is not really a gleamy pattern.
Maybe you could do a regex search
Wait nvm the regex match doesn't give you the index 
Thanks for the example... would that stop once found? It seems like it would continue on processing the entire list (and return the last found index instead of the first)
I see there are no default parameter values in gleam - is there any idiomatic way to add a start_at parameter or do you just accept that you'll need to pass 0 for that param every call?
There's no way to do an early return / break, so we need to process the entire list
But the solution can be modified to keep the first match
For default parameters, the gleamy way is usually to provide a function with sane defaults, and to provide another one with all the bells-whistles-parameterization
How about
pub fn main() {
let _ = index_of("", in: "Hello, world!") |> io.debug
let _ = index_of("Hello", in: "Hello, world!") |> io.debug
let _ = index_of("world", in: "Hello, world!") |> io.debug
index_of("bye", in: "Hello, world!") |> io.debug
}
pub fn index_of(sub part: String, in whole: String) -> Result(Int, Nil) {
do_index_of(part, whole, 0)
}
fn do_index_of(part, whole, index) {
case string.starts_with(part, whole) {
True -> Ok(index)
False -> case whole {
"" -> Error(Nil)
_ -> do_index_of(part, string.drop_left(whole, 1), index + 1)
}
}
}
use a function from stdlib to compare (assuming that is most efficient); recursion to stop when match found
(except the code above doesn't work correctly)

now it does