Сглаживание и взятие общей длины прекрасно работает:
1> L = ["hello","world wide","1","2","3"].
["hello","world wide","1","2","3"]
2> string:length(lists:flatten(L)).
18
Вы можете альтернативно суммировать длину каждой части:
3> lists:sum([length(S) || S <- L ]).
18
Или вы можете реализовать limit_word
функция выглядит следующим образом:
-module(hello).
-export([limit_word/2]).
limit_word(L, Max) ->
limit_word(L, Max, {0, []}).
limit_word([H|T], Max, {Size, Acc}) ->
NewSize = Size + length(H),
case NewSize > Max of
false ->
limit_word(T, Max, {NewSize, [H|Acc]});
true->
lists:reverse(Acc)
end;
limit_word([], _, {_, Acc}) ->
lists:reverse(Acc).
limit_word/2
- это то, что экспортируется в вызывающую программу (так же, как в исходном примере).Он просто вызывает функцию limit_word/3
, которая принимает дополнительный аргумент: кортеж с текущей общей длиной Size
и накопленные слова Acc
.Мы берем заголовок списка, добавляем его длину к Size
, и, если сумма меньше Max
, мы вызываем limit_word/3
рекурсивно, передавая NewSize
и новый список слов с новым словом в качестве егоголова и существующий список слов, как его хвост.Но если NewSize
превышает Max
, мы возвращаем перевернутый список Acc
- перевернутый, потому что мы сформировали список, добавив новые слова в заголовок.Это работает так, как вы ожидаете:
4> hello:limit_word(["Hello", "there my friend", "wassup!"],10).
["Hello"]
5> hello:limit_word(["Hello", "there my friend", "wassup!"],22).
["Hello","there my friend"]
Обновление: если общая длина всех элементов списка меньше Max
, мы никогда не используем случай true
, поэтому окончательный limit_word/3
предложение обрабатывает пустой список ввода, возвращая обратный аккумулятор.