Haskell列表清单

时间:2014-07-05 20:06:20

标签: haskell

我想将列表列表中的每个项目与其他元素进行比较,例如

[[1,2,3], [0,2,2], [1,4,5], [3,1,1]] 

比较[1,2,3]和[0,2,2]并应用一个操作(例如,距离公式“sqrt((x2-x1)^ 2 +(y2-y1)^ 2) “并且该操作的结果用一个保护器评估它,然后比较[1,2,3]到[1,4,5],然后结束列表,然后用[0,2.2]到[1,4] ,等等......

我正考虑采取(头部i)和尾部(头部i)进行比较,但不知道如何继续迭代比较

你们能告诉我如何做到这一点吗?谢谢

修改

我需要的是这个,第一个列表列表我需要根据距离公式制作另一个列表列表并比较列表的第3个元素,例如

    [[1,2,3], [0,2,2], [1,4,5], [3,1,1]] 

     [x1,y1,z1], [x2,y2,z2]
    sqrt ((x2-x1)^2+(y2-y1)^2)) if result_of_sqrt < z1 then 1:[do the same thing with the other element]                    
else 0:[do the same thing with the other element]

sqrt ((0-1)^2+(2-2)^2) ) = 1, 1 < 3 => 1:(compare this two elements [1,2,3],[1,4,5]) and so...

3 个答案:

答案 0 :(得分:4)

这个问题真的不清楚,但听起来,从根本上说,你想要获取列表中的每个元素并将其与列表中所有其余元素进行比较。假设我们要将[1..3]中的所有元素配对,其中顺序并不重要,即我们想要列表:

`[(1, 2), (1, 3), (2, 3)]`

我们可以直接这样做:

pairAll :: [a] -> [(a, a)]
pairAll [] = []
pairAll (x:xs) = map (\y -> (x, y)) xs ++ pairAll xs

根据需要pairAll [1..3] == [(1, 2), (1, 3), (2, 3)]。我们可以将配对功能分解为:

doStuffToAll :: (a -> a -> b) -> [a] -> [b]
doStuffToAll _ [] = []
doStuffToAll f (x:xs) = map (f x) xs ++ doStuffToAll f xs

然后pairAll = doStuffToAll (\x y -> (x, y))

将lambda表达式替换为列表的比较函数(即doStuffWithAll compareLists),如果我理解你的问题,那就应该这样做。

答案 1 :(得分:2)

这似乎产生了您的最后一个示例结果:

f xs = map (\x -> map (test x) xs) xs
  where test a@[x1,y1,z1] b@[x2,y2,z2] = 
          if a == b 
             then 0 
             else if sqrt ((x2 - x1) ^ 2 + (y2 - y1) ^ 2) < z1 
                     then 1 
                     else 0

或使用警卫代替ifelse

f xs = map (\x -> map (test x) xs) xs
  where test a@[x1,y1,z1] b@[x2,y2,z2] 
          | a == b    = 0 
          | m < z1    = 1 
          | otherwise = 0
    where m = sqrt ((x2 - x1) ^ 2 + (y2 - y1) ^ 2)

输出:

*Main> f [[0,0,4], [2,4,2], [1,3,5], [3,1,1]]
[[0,0,1,1],[0,0,1,0],[1,1,0,1],[0,0,0,0]]

答案 2 :(得分:1)

我不确定我是否正确理解你,但也许这会帮助你解决问题:

  1. 配对所有元组
  2. 应用您的比较&#39;函数到那些元组并输出一个真/假
  3. lol :: [(Int,Int,Int)]
    lol =  [(1,2,3), (0,2,2), (1,4,5), (3,1,1)]
    
    -- Use list comprehension to get all your unique pairs
    tuples = [(x,y) | x <- lol, y <- lol, x > y]
    
    result = map myCompare tuples
    
    -- myCompare takes a tuple of two 3-vector tuples and does an operation on them
    -- It outputs the two vectors it and a True/False
    myCompare (x@(x1,y1,z1),y@(x2,y2,z2)) = if ( (x1-x2)^2 + (y1-y2)^2 < (z2-z1)^2 ) then (x,y,True) else (x,y,False)       
    

    输出:

    tuples = [((1,2,3),(0,2,2)),((1,4,5),(1,2,3)),((1,4,5),(0,2,2)),((3,1,1),(1,2,3)),((3,1,1),(0,2,2)),((3,1,1),(1,4,5))]
    
    result = [((1,2,3),(0,2,2),False),((1,4,5),(1,2,3),False),((1,4,5),(0,2,2),True),((3,1,1),(1,2,3),False),((3,1,1),(0,2,2),False),((3,1,1),(1,4,5),True)]