[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