1

I've got a list of tuples inside another list and I am having problems finding the average.

I've checked over the asked questions and around the internet but most of the time they don't cover adding all of the tuples together and diving.

My list tuple list is [(String, Int)] and I want to be able to find the average of all of the tuples.

JamieB
  • 923
  • 9
  • 30

4 Answers4

4

You can easily transform that to a list of simple integers with map snd. So basically, sum $ map snd listOfTuples to add them all together. (To efficiently calculate an average, you might want to do something a little more sophisticated, but this should put you on the right track.)

Chuck
  • 234,037
  • 30
  • 302
  • 389
  • 2
    This hint points towards the idiomatic Haskell style for solving this kind of problem. You can also solve it (possibly more efficiently?) by using a recursive helper function, or by using `foldl'`, but both these methods are longer and arguably less clear, as well as being less idiomatic... – comingstorm Apr 17 '12 at 00:28
1

Also, given a list of the form [(String,Int)] you may use the unzip function, which has type

[(a,b)] -> ([a],[b])

So to get the average of a list that looks like [(String,Int)], you would simply use:

(sum $ snd $ unzip myList) / length(myList)

You'll need to correct the type so that you can divide using the fromIntegral function.

So, you might write the following function:

average :: [(a,Int)] -> Double

average xs = (fromIntegral $ sum $ snd $ unzip xs) / (fromIntegral $ length xs)

rotskoff
  • 714
  • 3
  • 10
0

If you search the net, you find many average :: (Real a, Fractional b) => [a] -> b functions, e.g. here.

So you just need a function of type [(String, Int)] -> [Int], then you can put the two together.

Community
  • 1
  • 1
dave4420
  • 46,404
  • 6
  • 118
  • 152
0

Here's a way to calculate the sum and length in a single pass.

It's not pretty, but it works.

averageTuples ts = let results = calculateSum ts 
    in (fst results)/(snd results)

calculateSum ts = foldr acc (0,0) $ zip (map snd ts) (repeat 1) where
    acc (x, y) (x', y') = (x+x', y+y')

main = print $ averageTuples [("foo", 1.09), ("bar", 2.6789), ("baz", 3.4)]

Keep in mind that you might have to use fromIntegral if you have a list of all Ints

Wes
  • 2,100
  • 1
  • 17
  • 31