Rob
Rob

Reputation: 37

Calculate mean of a list inside a tuple

I’m trying to compute the mean, given a list that has this structure:

lData = [("A", "EXP1", 5),("A", "EXP2", 9),("B", "EXP15", 8),("C", "EXP16", 7),("B", "EXP24", 4)]

First I group the elements by the first element of the tuple, and get this list of tuples that has as second element the list where I’m willing to compute the mean:

[("A", [5,9]),("B", [8,4]), ("C", [7])]

When I try to call the function computeMean I get an error. I try to get the array of numbers first by doing snd . head $ myGroup lData and get [5,9] and that’s OK. But don’t know how to go on from there.

I’ve created the function computeMean that given a list, returns the mean of the elements of the list.

computeMean $ snd . head $ myGroup lData gets the mean properly, but don’t know how apply it to all the elements.

The result I’m looking for is a list containing the first element of the tuple and the mean, such as:

[(“A”,7), (“B”,6), (“C”,7)]

But cannot get it right. Any advice?

import Data.Function (on)
import Data.List (sortBy, groupBy)
import Data.Ord (comparing)

fst3 :: (a, b, c) -> a
fst3 (x, _, _) = x

nextElem :: (a, b, c) -> (c)
nextElem (_, _, c) = (c)

myGroup :: (Eq a, Ord a) => [(a, b, c)] -> [(a, [c])]
myGroup = map (\l -> (fst3 . head $ l, map nextElem l)) . groupBy ((==) `on` fst3) . sortBy (comparing fst3)          
          
computeMean :: [Double] -> Double
computeMean [] = 0
computeMean (a) = sum a / fromIntegral(length a)

lData = [("A", "EXP1", 5),("A", "EXP2", 9),("B", "EXP15", 8),("C", "EXP16", 7),("B", "EXP24", 4)]

main = do
       print $ myGroup lData
       computeMean  $ snd . head $ myGroup lData
      

Upvotes: 0

Views: 65

Answers (1)

Z-Y.L
Z-Y.L

Reputation: 1779

Well, you just lack the last step:

-- A new function to compute the mean value in the tuple
meanTuple :: (String, [Double]) -> (String, Double)
meanTuple (k, v) = (k, computeMean v)

main = print . map meanTuple . myGroup $ lData

Upvotes: 1

Related Questions