Эрланг, заменяя атом другим в списке - PullRequest
1 голос
/ 29 апреля 2011

Я хочу написать функцию для замены определенного атома данным атомом во входном списке.Но я хочу сделать это с помощью сопоставления с образцом, а не с помощью условных операторов.Любая идея?

А также я хочу написать функцию, которая возвращает уникальные атомы в выражении.например,

Вход:

[a, b, c, a, b]   

Выход:

c

Вход:

[b, b, b, r, t, y, y]   

Выход:

[t, r]

Ответы [ 2 ]

1 голос
/ 29 апреля 2011

Предполагая, что вы хотите заменить все экземпляры и сохранить порядок списка (работает со всеми терминами):

replace(Old, New, List) -> replace(Old, New, List, []).

replace(_Old, _New, [],           Acc) -> lists:reverse(Acc);
replace(Old,  New,  [Old|List],   Acc) -> replace(Old, New, List, [New|Acc]);
replace(Old,  New,  [Other|List], Acc) -> replace(Old, New, List, [Other|Acc]).

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

Было бы очень неудобно реализовывать такую ​​функцию, используя только сопоставление с шаблоном в заголовках функций, и вы бы ничего не получили (производительность) от нее.Неловкость может возникнуть из-за необходимости циклически проходить как по рассматриваемому списку, так и по спискам, сохраняя ваше состояние уже проанализированных элементов.Вы также потеряете много читабельности.

Я бы порекомендовал пойти на что-то более простое (работает со всеми терминами, а не только с атомами):

unique(List) -> unique(List, []).

unique([], Counts) ->
    lists:foldl(fun({E, 1}, Acc) -> [E|Acc];
                   (_,      Acc) -> Acc
                end, [], Counts);
unique([E|List], Counts) ->
    unique(List, count(E, Counts).

count(E, [])            -> [{E, 1}];
count(E, [{E, N}|Rest]) -> [{E, N + 1}|Rest];
count(E, [{X, N}|Rest]) -> [{X, N}|count(E, Rest)].
0 голосов
/ 29 апреля 2011

Один из способов, которым я ищу решение вашего первого вопроса, состоит в том, чтобы использовать охрану вместо утверждений if.Использование только сопоставления с образцом не представляется возможным (или нежелательным, даже если вы можете это сделать).

Так, например, вы можете сделать что-то вроде:

my_replace([H|T], ToReplace, Replacement, Accum) when H == ToReplace ->
    my_replace(T, ToReplace, Replacement, [Replacement|Accum]);

my_replace([H|T], ToReplace, Replacement, Accum) ->
    my_replace(T, ToReplace, Replacement, [H|Accum]);

my_replace([], ToReplace, Replacement, Accum) ->
    lists:reverse(Accum).

РЕДАКТИРОВАТЬ: Отредактировано для простоты и стиля, спасибо за комментарии.:)

Что касается второй части вашего вопроса, что вы считаете "выражением"?

РЕДАКТИРОВАТЬ: не имеет значения, usort не полностью удаляет дубликаты, извините.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...