I want to ensure the elements in the array are unique.
4> A=[1,2, 3].
[1,2]
5> lists:nth(1, A) /= lists:nth(2, A).
true
6> lists:nth(1, A) /= lists:nth(2, A) /= lists:nth(3, A).
* 1: syntax error before: '/='
Unfortunately the '/=' does not work in the prompt #6 when I extend it to a three or more elements use case.
What is the acceptable erlang syntax?
i guess proper way is to make set from the list and then compare set size and list length. Kind of
A = [1,2,3].
S = sets:from_list(A).
length(A) == sets:size(S).
If your array has a fixed, compile-time known length (then you should use tuples) and you can pattern-match it:
case A of %% Size = 3
{_,X,X} -> true;
{X,_,X} -> true;
{X,X,_} -> true;
{_,_,_} -> false
end
Otherwise, I guess you'll go this very inefficient way.
Related
The set list whose length is a multiple of 4. Delete the first quarter of the list, and elements of the 3rd arranged in reverse order given. This is my variant ->
-import(lists, [filter/2, member/2, split/2, reverse/1]).
foo(L) when (length(L) rem 4) =/= 0 -> "Your list in non-multiple to 4!!!";
foo(L) -> {Sub1, Sub2} = split(length(L) div 2, L),
{ _ ,Second} = split(length(Sub1) div 2, Sub1),
{Third,Fourth} = split(length(Sub2) div 2, Sub2),
Second ++ reverse(Third) ++ Fourth.
May be someone has any better idea how to do that. Thanks!
I have quite efficient solution:
2> timer:tc(fun(L) -> fun() -> F(L) end end(lists:seq(1, 1000000))).
{22770,
[250001,250002,250003,250004,250005,250006,250007,250008,
250009,250010,250011,250012,250013,250014,250015,250016,
250017,250018,250019,250020,250021,250022,250023,250024,
250025,250026,250027|...]}
3> timer:tc(fun(L) -> fun() -> F(L) end end(lists:seq(1, 32))).
{79,
[9,10,11,12,13,14,15,16,24,23,22,21,20,19,18,17,25,26,27,28,
29,30,31,32]}
How much will you pay me for F/1 definition?
Make a function that takes two arguments, an integer and a five element tuple of integers that returns true if the sum of any three elements of the tuple is greater than the first argument, else false.
let func el tupl =
match tupl with
|(a,b,c,d,e) when (a+b+c) > el || (a+d+e) > el || (b+c+d)> el || (b+c+e) > el -> true
| _-> false
There isn't really an advantage to using an explicit match expression in this case, you can solve the problem using when guards as you suggested in your question but it transfers a lot of the thinking burden to you.
Here is an alternative:
let inline func el (a,b,c,d,e) =
let sum3 =
[a; b; c; d; e] // create a list of elements
|> List.sortDescending // sort list by descending
|> List.take 3 // take the 3 largest elements
|> List.sum // sum them
sum3 > el // if not true for 3 largest, it's not true for any
Note: I made the function inline so it would work with any type that supports comparison and +. You could remove the inline and just accept, for example ints.
HeirListFormatted = [{code, 1}, ...],
HeirCode = proplists:get_value(code, HeirListFormatted),
HeirList = [<<"1">>, <<"2">>, ...],
HeirListCodes = [case to_integer(X) of HeirCode -> []; _-> form_data:to_integer(X) end || X <- HeirList].
Here HeirListCodes is returning a list like this: [[],2, 3,[],...]. But I want the code in one line and HeirListCodes should return me a list like [2,3, ...].
Thank you inadvance!
Is it what you are looking for?
[Y || X <- HeirList , Y <- [binary_to_integer(X)],Y =/= HeirCode].
[Edit]
if HeirCode == undefined:
Without any change, the filter condition will be always true, and you will get the list of binaries transformed onto a list of integer.
If you add the filter condition HeirCode =/= undefined this filter will be always false, so the result will be an empty list.
So the solution really depend on the result you expect.
I have this variable Code in erlang which has this value "T00059"
I want to extract this value 59 from Code.
I try to extract with this code this value "00059".
NewCode = string:substr(Code, 2, length(Code)),
Now I want to know how can we eliminate the first zero before the first integer not null. I mean how can we extract "59"?
For example if I have this value "Z00887" I should have in the final this value 887.
You can simply do (output from an interactive erlsession):
1> Code = "Z00887",
1> {NewCode, _Rest} = string:to_integer(string:substr(Code, 2, length(Code))),
1> NewCode.
887
(My answer in test with loop in erlang goes into more detail regarding the same problem)
This code will skip starting zeros. If you want to save them change $1 to $0
extract_integer([]) -> [];
extract_integer([H|T]) when (H >= $1) and (H =< $9) -> [H] ++ T;
extract_integer([_H|T]) -> extract_integer(T).
I am looking for a way to find tuples in a list in Erlang using a partial tuple, similarly to functors matching in Prolog. For example, I would like to following code to return true:
member({pos, _, _}, [..., {pos, 1, 2}, ...])
This code does not work right away because of the following error:
variable '_' is unbound
Is there a brief way to achieve the same effect?
For simple cases it's better to use already mentioned lists:keymember/3. But if you really need member function you can implement it yourself like this:
member(_, []) ->
false;
member(Pred, [E | List]) ->
case Pred(E) of
true ->
true;
false ->
member(Pred, List)
end.
Example:
>>> member(fun ({pos, _, 2}) -> true; (_) -> false end, [..., {pos, 1, 2}, ...]).
Use lists:keymember/3 instead.
You can do it with a macro using a list comprehension:
-define(member(A,B), length([0 || A <- B])>0).
?member({pos, _, _}, [{width, 17, 42}, {pos, 1, 2}, totally_irrelevant]).
It is not very efficient (it runs through the whole list) but it is the closest I can think to the original syntax.
If you want to actually extract the elements that match you just remove 'length' and add a variable:
-define(filter(A,B), [_E || A =_E <- B]).
You could do it using list comprehension:
Matches = [ Match || {Prefix, _, _} = Match <- ZeList, Prefix == pos].
Another possibility would be to do what match specs do and use the atom '_' instead of a raw _. Then, you could write a function similar to the following:
member(X, List) when is_tuple(X), is_list(List) ->
member2(X, List).
% non-exported helper functions:
member2(_, []) ->
false;
member2(X, [H|T]) when not is_tuple(H); size(X) =/= size(H) ->
member2(X, T);
member2(X, [H|T]) ->
case is_match(tuple_to_list(X), tuple_to_list(H)) of
true -> true;
false -> member2(X, T)
end.
is_match([], []) ->
true;
is_match(['_'|T1], [_|T2]) ->
is_match(T1, T2);
is_match([H|T1], [H|T2]) ->
is_match(T1, T2);
is_match(_, _) ->
false.
Then, your call would now be:
member({pos, '_', '_'}, [..., {pos, 1, 2}, ...])
This wouldn't let you match patterns like {A, A, '_'} (checking where the first two elements are identical), but if you don't need variables this should work.
You could also extend it to use variables using a similar syntax to match specs ('$1', '$2', etc) with a bit more work -- add a third parameter to is_match with the variable bindings you've seen so far, then write function clauses for them similar to the clause for '_'.
Granted, this won't be the fastest method. With the caveat that I haven't actually measured, I expect using the pattern matching in the language using a fun will give much better performance, although it does make the call site a bit more verbose. It's a trade-off you'll have to consider.
May use ets:match:
6> ets:match(T, '$1'). % Matches every object in the table
[[{rufsen,dog,7}],[{brunte,horse,5}],[{ludde,dog,5}]]
7> ets:match(T, {'_',dog,'$1'}).
[[7],[5]]
8> ets:match(T, {'_',cow,'$1'}).
[]