[Haskell-beginners] Again on List Manipulation
Henry Olders
henry.olders at mcgill.ca
Sun Sep 12 10:21:57 EDT 2010
On 2010-09-12, at 7:57 , Lorenzo Isella wrote:
> Dear All,
> First of all, thanks to the whole list for their help.
> I am still struggling with things I used to be able to do quite easily
> (though maybe not efficiently) with other languages. I still have to get
> used to the immutable nature of lists and the absence of for loops.
> Let us say you have two lists
>
> l = [1,1,1,1,2,2,2,2,2,2,2,3,3,5,6,7] (already sorted)
>
> and a list of corresponding values for every entry in l
>
> m= [2,2,2,2,4,4,4,4,6,6,4,4,4,10,12,14].
> Also consider the list of the unique values in l
>
> l_un = nub l
>
> Now, what I would like to do is to get a third list, let us call it q,
> such that its length is equal to the length of l_un.
> On top of that, its i-th entry should be the sum of the entries of m
> corresponding to the i-th values of l_un.
> To fix the ideas, q should be
>
> q = [8,32, 8,10,12,14] .
> How would you do that?
>
> Cheers
>
> Lorenzo
>
> P.S.: I will need this function both with Integer and Double numbers (I
> may have situation in which the entries of one list or both are real
> numbers, though the goal stays the same)
Hi, Lorenzo!
As you may have gathered, I'm a big fan of list comprehensions.
First, I renamed your lists (better readability later on; also, I used bs instead of l, as l is easy to confuse with the vertical stroke character | required in list comprehensions):
Prelude Data.List> let bs = [1,1,1,1,2,2,2,2,2,2,2,3,3,5,6,7]
Prelude Data.List> let ms = [2,2,2,2,4,4,4,4,6,6,4,4,4,10,12,14]
Prelude Data.List> let us = nub ls
Next, use a list comprehension to give me the same number of elements as in us:
Prelude Data.List> [u | u <- us]
[1,2,3,5,6,7]
Nest a list comprehension inside of that, so that each element now is list ms:
Prelude Data.List> [[m | m <- ms] | u <- us]
[[2,2,2,2,4,4,4,4,6,6,4,4,4,10,12,14],[2,2,2,2,4,4,4,4,6,6,4,4,4,10,12,14],[2,2,2,2,4,4,4,4,6,6,4,4,4,10,12,14],[2,2,2,2,4,4,4,4,6,6,4,4,4,10,12,14],[2,2,2,2,4,4,4,4,6,6,4,4,4,10,12,14],[2,2,2,2,4,4,4,4,6,6,4,4,4,10,12,14]]
Introduce the elements of list bs, as we will need them for filtering:
Prelude Data.List> [[m | (b,m) <- zip bs ms] | u <- us]
[[2,2,2,2,4,4,4,4,6,6,4,4,4,10,12,14],[2,2,2,2,4,4,4,4,6,6,4,4,4,10,12,14],[2,2,2,2,4,4,4,4,6,6,4,4,4,10,12,14],[2,2,2,2,4,4,4,4,6,6,4,4,4,10,12,14],[2,2,2,2,4,4,4,4,6,6,4,4,4,10,12,14],[2,2,2,2,4,4,4,4,6,6,4,4,4,10,12,14]]
Filter by comparing the elements of bs and us, ie b == u:
Prelude Data.List> [[m | (b,m) <- zip bs ms, b == u] | u <- us]
[[2,2,2,2],[4,4,4,4,6,6,4],[4,4],[10],[12],[14]]
Finally, sum each list:
Prelude Data.List> [sum [m | (b,m) <- zip bs ms, b == u] | u <- us]
[8,32,8,10,12,14]
Henry
More information about the Beginners
mailing list