My homework task is to group two tuples in a list if the second element of the first tuple is the same as the first element of the second tuple. Then, if the first tuple is (a, b) and the second is (b, c), the tuple (a, c) must be added to the result list.
I wrote first function wich takes element with one tuple and second list with many tuples and compare each to each.
this one works correcly:
c1 = ("a","x")
d1 = [ ("x","b"), ("z","c"), ("x","b"), ("z","c")
, ("x","b"), ("z","c"), ("x","b"), ("z","c") ]
getByOne c1 a1 = filter (/=[])
[ if (fst (last(take n a1))) == (snd c1)
then [((fst c1), (snd (last(take n a1))))]
else [] | n <- [1..(length a1) ] ]
output:
[ [("a","b")], [("a","b")], [("a","b")], [("a","b")] ]
But the problems is that I can’t throw in if then and else statement just simple tuple, so I create a new list. In the end of this “workaround” i am getting list in list in list and so on. Also if output list was bigger, there were be more lists in lists.
Is there any way to pass out only tuple or empty tuple or i should somehow group theses lists ?
You can flatten the result using
then you don’t even need to
filter (/=[])– by the way, the condition(/= [])is more idiomatically writtennot . null, since thenulltest doesn’t impose anEqconstraint on its argument (you already have one here, so it’s just a matter of idiom).Further,
last (take n a1)is just then-th element ofa1if1 <= n <= length a1. Since you have that restriction imposed, that can more succinctly be expressed asa1 !! (n-1)Then you have structurally
(I have shifted indices to index by
i), which is clearer and more efficiently expressed asIf you prefer a list comprehension to
map, you can also write that aswhich in your case, using the ability to pattern-match in alist-comprehension generator, gives us
which is much shorter and more readable. Instead of using
if condition then [element] else []andconcat, even nicer is to use a condition in the list comprehension,which is short and clear.