2015-04-06 3 views
1

Я использую ядро ​​Janestreet, и я хочу в основном делать String.map str (Char.to_int), но String.map требует функцию be (char -> char) и возвращает строку (а не список по мере необходимости)). Альтернатива, которую я знаю, это использовать цикл for и составить список, но это не очень FPish. Есть ли карта, которая берет строку и (char -> 'a) и возвращает список?Map (char -> int) over String

ответ

1

Я вижу функцию с именем to_list_rev в расширении ядра модуля String. Он переводит строку в обратный список символов. Таким образом, вы могли бы сделать что-то вроде этого:

List.rev_map Char.to_int (String.to_list_rev s) 

Update

Оказывается, что в ядре, String также Container. Ссылка на Контейнер не работает в документации, но я думаю, что это означает, что есть функция to_list, которая кажется более естественной в использовании.

Таким образом, даже если вы не хотите идти по этому пути, этот код кажется опрятнее, чем выше:

List.map Char.to_int (String.to_list s) 
+0

Эх .. Я все еще надеюсь на лучший ответ. –

+0

Я не обвиняю вас :-) Fwiw, было бы не так сложно просто написать нужную функцию карты. –

+0

Я закончил тем, что принял ваш совет. –

0

написал свой собственный, как Джефф предложил. Должна быть разумно эффективной.

let rec str_map_helper str f acc ind = 
    if ind = -1 
     then acc 
     else str_map_helper str f ((f str.[ind])::acc) (ind - 1);; 

let string_map str f = 
    str_map_helper str f [] ((String.length str) - 1);; 

Это, вероятно, должно быть сделано как вложенная функция.

+1

Это определение не будет работать с пустыми строками. – Romildo

+0

@ Romildo: Спасибо, что указали это. Решение состояло бы в том, чтобы str_map_helper немедленно возвращал acc, если ind = -1, я бы отредактировал код, но у моего текущего компьютера нет OCaml. –

1

Все функции карты возвращают один и тот же контейнер, но с различными элементами. Самое легкое решение будет:

String.to_list str |> List.map ~f:Char.to_int 

Это очень хорошо, и очень распространенная идиома. Конечно, вы можете использовать rev_map, чтобы ускорить вещи немного:

String.to_list_rev str |> List.rev_map ~f:Char.to_int 

Еще один, более громоздким вариантом было бы построить новый список, а развернув строку с помощью функции List.init:

let to_codes str = 
    List.init (String.length str) ~f:(fun n -> 
    Char.to_int str.[n]) 
Смежные вопросы