【问题标题】:Haskell list of list'sHaskell 列表的列表
【发布时间】:2014-07-05 20:06:19
【问题描述】:

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

[[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] 进行比较,5] 等等...

本来想拿(head i)和tail(head i)比较,但是不知道怎么继续迭代比较

你们能给我一个关于如何做到这一点的想法吗?谢谢你

编辑

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

    [[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...

【问题讨论】:

  • 这个描述不清楚。你期待什么输出?
  • 在操作和守卫之后,我将根据结果创建一个包含 0 和 1 的列表列表,例如 [1,0,1],[0,0,0],[1 ,1,0],[1,0,1]
  • 问题陈述中的类型签名错误。应该是[[Int]] -&gt; [[Int]]

标签: haskell


【解决方案1】:

这个问题确实不清楚,但听起来,从根本上讲,您希望获取列表中的每个元素并将其与列表中的所有其余元素进行比较。假设我们要配对 [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 -&gt; (x, y))

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

【讨论】:

  • 嗨,感谢您的回答,我刚刚编辑了解释问题的原始帖子!
【解决方案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]]

【讨论】:

  • 谢谢!有没有办法使用警卫而不是使用 if else 来做到这一点?
  • @user3806679 当然,为什么不呢?请参阅编辑后的答案。
  • 你可以使用嵌套的where来美化表达式:... | m &lt; z1 = 1 ... where m = sqrt ...
【解决方案3】:

我不确定我是否理解正确,但也许这会帮助你弄清楚:

  1. 将所有元组配对
  2. 将“比较”函数应用于这些元组并输出真/假

.

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)]

【讨论】:

    猜你喜欢
    • 2021-08-06
    • 1970-01-01
    • 2015-12-09
    • 1970-01-01
    • 2020-08-19
    • 1970-01-01
    • 1970-01-01
    • 2021-03-02
    • 1970-01-01
    相关资源
    最近更新 更多