For example I have a list [1,3,5] and another list [2,4,6], how do I append these two lists in such way it will form into a List of Lists like this: [[1,3,5],[2,4,6]]?
How do I manipulate the list if I add another list at the end [7,8,9] to look like [[1,3,5],[2,4,6],[7,8,9]]?
L1 = [1,3,5],
L2 = [2,4,6],
[L1,L2].
You just need create a list containing both lists.
A = [1,3,5],
B = [2,4,6],
[A, B].
-module(lol).
-export([new/0, append/2, head/1, tail/1]).
new() -> [].
append(H, []) when is_list(H) -> [H];
append(H, T) when is_list(H) -> [H | T].
head([H | _]) when is_list(H) -> H.
tail([_ | T]) -> T.
In the shell you could then:
> Herp = lol:append([1,3,4], lol:new()).
[[1,2,3]]
> Derp = lol:append([4,5,6], Herp).
[[4,5,6],[1,2,3]]
> lol:head(Derp).
[4,5,6]
I leave the rest as exercise for the user.
1> [1,2,3 | [1,2,3]].
[1,2,3,1,2,3]
2> lists:append([1,2,3], [1,2,3]).
[1,2,3,1,2,3]
Related
I want to create a function that rearranges the elements of a list.
For example the list [1,2,3] will produce:
[1,2,3]
[1,3,2]
[2,1,3]
[2,3,1]
[3,1,2]
[3,2,1]
The order isn't important.
If I write this list comprehension:
[[a,b,c] | a <- l, b <- l, c <- l, a /= b, a /= c, b /= c]
It works (where l is the desired list). Problem is I want to do this for an undefined number of list elements
Yes. The Data.List module has a permutations :: [a] -> [[a]] function to generate all permutations. This does not only work on three or more elements, but it does not use an Eq typeconstraint. If a list contains two items that are equal, then you can still consider it a different permutation when we swap the two.
We can furthermore implement such function ourself. We can first make a helper function that is given a list and returns a list of 2-tuples where the first item contains the value we "picked", and the second item a list of remaining elements:
pick :: [a] -> [(a, [a])]
pick [] = []
pick (x:xs) = (x, xs) : map prep (pick xs)
where prep (y, ys) = (y, x:ys)
For example:
Prelude> pick [1,4,2,5]
[(1,[4,2,5]),(4,[1,2,5]),(2,[1,4,5]),(5,[1,4,2])]
Next we can use recursion to each time pick an element, and recurse on the remaining elements:
perms :: [a] -> [[a]]
perms [] = [[]]
perms xs = [ p : ps | (p, ys) <- pick xs, ps <- perms ys ]
This then yields:
Prelude> perms [1,4,2,5]
[[1,4,2,5],[1,4,5,2],[1,2,4,5],[1,2,5,4],[1,5,4,2],[1,5,2,4],[4,1,2,5],[4,1,5,2],[4,2,1,5],[4,2,5,1],[4,5,1,2],[4,5,2,1],[2,1,4,5],[2,1,5,4],[2,4,1,5],[2,4,5,1],[2,5,1,4],[2,5,4,1],[5,1,4,2],[5,1,2,4],[5,4,1,2],[5,4,2,1],[5,2,1,4],[5,2,4,1]]
I have implemented a function which deleting elements of a list one by one:
remove(_,[])->
[];
remove(Elem, L)->
Rest = lists:delete(Elem,L),
remove(Elem,Rest).
But it hangs when I tried with this example:
L = [1,2,3,4].
remove(hd(L), [L]).
What is wrong with it? Or is there a better way to delete elements in the list one by one starting from the first element of a list.
It makes an infinite loop. First, you call
remove(1, [1,2,3,4]) ->
[2,3,4] = lists:delete(1, [1,2,3,4]),
remove(1, [2,3,4]).
So you call
remove(1, [2,3,4]) ->
[2,3,4] = lists:delete(1, [2,3,4]),
remove(1, [2,3,4]).
And then you call it again with the same input and again and again.
One way to fix it is to check if lists:delete/2 returns same result
remove(Elem, L)->
case lists:delete(Elem,L) of
L -> L;
Rest -> remove(Elem,Rest)
end.
(Function clause remove(_,[]) is not necessary even it doesn't do any harm.)
But there is a more strightforward approach:
remove(_, []) -> [];
remove(H, [H|T]) ->
remove(H, T);
remove(X, [H|T]) ->
[H | remove(X, T)].
Which could be written using list comprehensions:
remove(X, L) ->
[Y || Y <- L, Y =/= X].
The resulting code will be basically the same.
You can also use the lists module, it has a lot of useful functions defined.
Take this for example, for you case:
1> A = [1,2,3,4,5,6,7,8,9,10].
[1,2,3,4,5,6,7,8,9,10]
2> B = [2,3,4].
[2,3,4]
3> lists:filter(fun (Elem) -> not lists:member(Elem, B) end, A ).
[1,5,6,7,8,9,10]
simple answer is
A = [1,2,3,3,4]
B = [3,4]
A -- B = C
[1,2,3,3,4] -- [3,4] = [1,2,3].
i want to create a functions that takes a list and creates a list of list with list comprehension with the form [[e1],[e1,e2],[e1,e2,e3]...].
For example:
f5 ['a','b','c'] = ["a","ab","abc"]
f5 [1,2,3] = [[1],[1,2],[1,2,3]]
My Code:
f5 xs = [a | a <- xs]
-- tests:
*Main> f5 ["a","b","c"]
["a","b","c"]
*Main> f5 [1,2,3]
[1,2,3]
You can do it like this:
f5 xs = [take index xs | (x, index) <- zip xs [1..]]
For each element in the list a tuple is created containing that element and it's index, starting at 1. Then, by using take, for each element in the zipped list an appropriate number of elements from the original list is taken. The number of elements to take is specified in the index.
Actually, we don't even need the x element from the tuple, so this could be rewritten as
f5 xs = [take index xs | (_ ,index) <- zip xs [1..]]
This also works
foldr (\x rest -> [x]:(map (x:) rest)) [] [1,2,3,4]
I have a list of tuples and I want to create the a list of elements from a specific position in the tuple.
My tuple is {A, B} and I have several of these in a list and i want to create the list of all the B elements.
Cheers!
You can use lists:map.
1> A = [{1,2},{3,4},{5,6}].
[{1,2},{3,4},{5,6}]
2> B = lists:map(fun ({_, V}) -> V end, A).
[2,4,6]
The function passed to the map will select the element required from the tuple and the result will be a list of all the elements in that particular position in the given list of tuples. The above code assumes that all tuples have same number of elements.
Yet another way is to just use a simple list comprehension:
[B || {_, B} <- L].
> L = [{a1,b1}, {a2,b2}, {a3,b3}].
[{a1,b1},{a2,b2},{a3,b3}]
> lists:foldr(fun({_, B}, Acc) -> [B | Acc] end, [], L).
[b1,b2,b3]
This is a quick sample, not tested, but it should work.
split_tuples([{A | B} | T], Acc) ->
NewAcc = [B | Acc],
split_tuples(T, NewAcc);
split_tuples([], Acc) ->
lists:reverse(Acc).
erlang's element/2 function does just that: return the nth element from a tuple.
Put that in a map or fold function, with position as a parameter, and you're done.
edit: some untested code example:
get_them_all(ListOfTuples,Index) ->
lists:map(fun(Tuple) -> element(Index,Tuple) end,ListOfTuples).
Why there is no List.skip and List.take? There is of course Seq.take and Seq.skip, but they does not create lists as a result.
One possible solution is: mylist |> Seq.skip N |> Seq.toList
But this creates first enumerator then a new list from that enumerator. I think there could be more direct way to create a immutable list from immutable list. Since there is no copying of elements internally there are just references from the new list to the original one.
Other possible solution (without throwing exceptions) is:
let rec listSkip n xs =
match (n, xs) with
| 0, _ -> xs
| _, [] -> []
| n, _::xs -> listSkip (n-1) xs
But this still not answer the question...
BTW, you can add your functions to List module:
module List =
let rec skip n xs =
match (n, xs) with
| 0, _ -> xs
| _, [] -> []
| n, _::xs -> skip (n-1) xs
The would-be List.skip 1 is called List.tail, you can just tail into the list n times.
List.take would have to create a new list anyway, since only common suffixes of an immutable list can be shared.