A = [1,2,3]
The output should be:
[1,one,2,two,3,three]
Is it possible to get such an output?
Yes, you can put two clauses in the comprehension and make the second one return two elements for each element in the first one:
1> F = fun
1> (1) -> "one";
1> (2) -> "two";
1> (3) -> "three"
1> end.
#Fun<erl_eval.6.127694169>
2> [B || A <- [1, 2, 3], B <- [A, F(A)]].
[1,"one",2,"two",3,"three"]
i think the out put of last code would be
[[1 ,"one"] , [2, "two"] , [3 , "tree"]].
some right answer will be
lists:append([begin T = case I of
1 -> "One" ;
2->"Two";
3->"Three";
_ -> "" end ,
[I ,T] end
|| I <- lists:seq(1,3)]).
Related
Why is the difference between two spawning methods listed below?
1> G = fun(X) -> io:format("~p ", [X]) end.
#Fun<erl_eval.44.97283095>
2> [spawn(fun() -> G(X) end) || X <- [1, 2, 3] ].
1 2 3 [<0.82.0>,<0.83.0>,<0.84.0>]
3> [spawn(fun() -> fun(X) -> io:format("~p ", [X]) end end) || X <- [1, 2, 3] ].
[<0.86.0>,<0.87.0>,<0.88.0>]
4>
In the last example, here is the function being spawned:
fun() ->
fun(X) -> io:format("~p ", [X]) end
end
It doesn't actually do anything - it creates an anonymous function but doesn't call it.
To call the function, you'd do something like this:
fun() ->
TheFunction = fun(Y) -> io:format("~p ", [Y]) end,
TheFunction(X)
end
(I changed the argument name from X to Y for clarity. It doesn't really matter, as function arguments overshadow variables from an outer scope.)
Or to fit it back in the one-liner:
4> [spawn(fun() -> TheFunction = fun(Y) -> io:format("~p ", [Y]) end, TheFunction(X) end) || X <- [1, 2, 3] ].
1 2 3 [<0.94.0>,<0.95.0>,<0.96.0>]
Now it behaves the same as the other example.
Thank you!
It's clear enough.
The anonymous function have to be named to be called. For example, if we pass anonymous function as a parameter to another function, it only can be called as a named argument inside wrapping function.
I can understand most of the [H|T] examples I read in the docs. I usually means that I want to use either the H or the T part of the list. What if I want to use the whole list instead. Sample code:
-module(module_variable).
-export([main/0, list_suffix/1]).
variable() -> [1, 2, 3, 4, 5].
list_suffix([_H|T]) ->
lists:suffix(variable, T).
main() ->
io:fwrite("~p~n", [list_suffix([4, 5])]).
The error I get is:
6> module_variable:list_suffix([1,[4, 5]]).
** exception error: bad argument
in function length/1
called as length(variable)
in call from lists:suffix/2 (lists.erl, line 205)
Help is appreciated.
You can use multiple values from the front of the list. You cannot skip an arbitrary number of values in the middle. Since in your code you don't know how many elements from the head you want to match ahead of time, pattern matching can't do this for you.
Some examples:
Setup:
1> A = [1, 2, 3, 4, 5].
[1,2,3,4,5]
Matches first 2 elements of list
2> [1, 2 | _ ] = A.
[1,2,3,4,5]
% Can pattern match to extract values
3> [B, C | _ ] = A.
[1,2,3,4,5]
4> B.
1
5> C.
2
Can match some constant values and also assign
6> [1, 2, D | _ ] = A.
[1,2,3,4,5]
Can match whole list
7> [1, 2, 3, 4, 5] = A.
[1,2,3,4,5]
% Can't skip over elements in the middle
8> [1, 2| [4, 5]] = A.
** exception error: no match of right hand side value [1,2,3,4,5]
% This works, though not useful most of the time:
9> [1, 2, 3 | [4, 5]] = A.
[1,2,3,4,5]
% Can assign every element
10> [B, C, D, E, F] = A.
[1,2,3,4,5]
11> E.
4
12> F.
5
% If you don't use a pipe, the length has to match exactly
13> [B, C, D, E] = A.
** exception error: no match of right hand side value [1,2,3,4,5]
Can I create a list with atoms as reference for them to later use it in my move method?
createLists(X) ->
List = [
listA = lists:seq(1, X),
listB = [],
listC = []
],
List.
Then I create like T = hello:createLists(10).
move(List, A, B) ->
...
How can I obtain A and B using atoms? I'm pretty new to Erlang so the answer might be obvious.
move is supposed to move top element of the from A to B but I struggle to pass A and B when I do like hello:move(List, ?, ?).
Regarding the code in your comment, #armedor:
1 move(List, a, b, c) ->
2 Source = proplists:get_value(a, List),
3 Dest = proplists:get_value(b, List),
4 Help = proplists:get_value(c, List),
5 Temp1 = [lists:nth(1,Source)],
6 NewDest = [lists:append(Dest,Temp1)],
7 NewSource = lists:subtract(Source,Temp1),
8 List1=[NewSource,NewDest,Help].
Say List is defined as [ {a, lists:seq(1, 3)}, {b, []}, {c, []} ].
Line 8 isn't going to be a proplist anymore, but just the sublists themselves. Instead, create List1 as [{a, NewSource}, {b, NewDest}, Help].
You also don't need to assign to List1 in line 8, since the function is returning - just make the new list itself the last line, which will be the return value.
And the lists:nth and lists:subtract you're doing can be combined as
[Temp1 | NewSource] = Source
Lets say I have:
[ X || X<- L, some_expensive_boolean(X), some_expensive_boolean2(X)]
If, for any X in L, some_expensive_boolean(X) is false, is some_expensive_boolean2(X) executed?
TL;DR: No, some_expensive_boolean2/1 is not called.
There a couple of ways you can verify this.
1. Having functions print something as they are called.
-module(lc).
-export([lc/1]).
lc(L) ->
[X || X <- L, f(X), g(X)].
f(X = 2) ->
erlang:display({f, 2}),
false;
f(X) ->
erlang:display({f, X}),
true.
g(X) ->
erlang:display({g, X}),
true.
Then on the Erlang shell:
1> lc:lc(lists:seq(1, 4)).
{f,1}
{g,1}
{f,2} %% g is not called here
{f,3}
{g,3}
{f,4}
{g,4}
[1,3,4]
2. Check the generated Core Erlang code.
Compiling the module with the +to_core option will produce a lc.core file with the Core Erlang code, which looks a little bit like Erlang but has its own syntax but very similar semantics.
erlc +to_core lc.erl
The code generated is quite verbose so I won't paste it here, but the gist is that there are two nested case expressions, one calling f/1 with the clause that matches on true containing the other case that calls g/1.
The answer is no. It is short-circuited.
1> [ X || X <-[1,2], begin io:format("Test 1: ~p~n", [X]), X rem 2 =:= 0 end, io:format("Test 2: ~p~n", [X]) =:= ok ].
Test 1: 1
Test 1: 2
Test 2: 2
[2]
Short-circuits based on the following:
-module(shortcircuit).
-export([test/0]).
test() ->
L = [1, 2, 3],
[ X || X <- L, some_expensive_boolean(X), some_expensive_boolean2(X)].
some_expensive_boolean(X) ->
io:format("In some_expensive_boolean: ~p~n", [X]),
false.
some_expensive_boolean2(X) ->
io:format("In some_expensive_boolean2: ~p~n", [X]),
true.
Execute:
1> shortcircuit:test().
In some_expensive_boolean: 1
In some_expensive_boolean: 2
In some_expensive_boolean: 3
[]
2>
Let's create an example:
$ cat test.erl
-module(test).
-export([show/0]).
show() ->
[ X || X <- [1,2,3,4,5], bigger(X), smaller(X)].
bigger(X) ->
io:format("bigger ~p~n", [X]),
X > 2.
smaller(X) ->
io:format("smaller ~p~n", [X]),
X < 4.
and test it:
14> c(test).
{ok,test}
15> test:show().
bigger 1
bigger 2
bigger 3
smaller 3
bigger 4
smaller 4
bigger 5
smaller 5
[3]
So the answer is: NO.
How to implement AND guards in list comprehensions? Separating the guards with comma seems to word as OR:
1> rd(r, {a, b}).
r
2> L = [#r{a = 1, b =2}, #r{a = 1, b = 3}].
[#r{a = 1,b = 2},#r{a = 1, b = 3}]
3> [X || X <- L, X#r.a =/= 1, X#r.b =/= 2].
[]
Thanks a lot.
That's definitely an AND. The first element fails both tests; the second fails the X#r.a =/= 1 test.
If you want OR, simply use the orelse operator:
2> [X || X <- L, X#r.a =/= 1 orelse X#r.b =/= 2].
[#r{a = 1,b = 3}]