Home > Enterprise >  Getting data from data list from conditions
Getting data from data list from conditions

Time:05-04

Im trying to get the user that is closer to (20.2,-1.00) and has a score higher than 7. However everything i try doesnt seem to work, and i keep getting stuck. The code below shows my most recent attempt. Any help would be great.

data User = User { name :: String
                    , location :: (Double,Double)
                    , score :: [Double] 
                    }

user1 = User {name = "BladeBoy", location = (50.45,-1.203),score = [10.2,5.6,7.8]}
user2 = User {name = "Kaslan", location = (60.78,1.003),score = [20,7.6,12.1]}
user3 = User {name = "Ryan", location = (50.0,-0.283),score = [10.2,7.8,7.8]}

users :: [User]
users = [user1,user2,user3]

near7Help :: [(Double, Double)] -> [(Double, Double)]
near7Help (x : xs) =  (near7 x ) near7Help >> xs

near7 :: (Double,Double) -> (Double,Double)
near7 x _  = snd . minimum . map (abs . subtract 7 &&& id)

getScores (User _ _ score) = score

-- output user nearest to 50.2,-0.4 and middle score higher than 7

CodePudding user response:

I do not see the exact definition of a distance and an s calculation in the assignment. So I've created two function to customize as needed:

s :: [Double] -> Double
distanceFrom :: (Double, Double) -> User -> Double

Then I created functions fulfilling your two criteria:

scoreHigherThan :: Double -> User -> Bool
scoreHigherThan a u
  = s (score u) > a

minDistance :: (Double, Double) -> [User] -> User
minDistance a (x:xs) = minDistance' a xs (distanceFrom a x) x

minDistance' :: (Double, Double) -> [User] -> Double -> User -> User
minDistance' _ [] d u = u
minDistance' a (x:xs) d u
  | d' < d = minDistance' a xs d' x
  | otherwise = minDistance' a xs d u
  where d' = distanceFrom a x

Then all you have to do is call:

near7 :: [User] -> User
near7 u = minDistance (50.2,-0.4) (filter (scoreHigherThan 7) u)

Here's an example of implementing the unknown s and distanceFrom functions:

s :: [Double] -> Double
s x = sum x / fromIntegral (length x)

distanceFrom :: (Double, Double) -> User -> Double
distanceFrom (f,g) User {name = b, location = (c,d), score = e}
  = (c-f)^2 (d-g)^2

Edit1: The minDistance using a foldr (without explicit recursion):

minDistance :: (Double, Double) -> [User] -> User
minDistance a (b:bs) = snd $ foldr (minDistance' a) (distanceFrom a b,b) bs

minDistance' :: (Double, Double) -> User -> (Double, User) -> (Double, User)
minDistance' p u' (d,u)
 | d' < d = (d',u')
 | otherwise = (d,u)
 where d' = distanceFrom p u'
  • Related