Reputation: 391
I want to compare each item in the list of lists with other elements, for example,
[[1,2,3], [0,2,2], [1,4,5], [3,1,1]]
compare [1,2,3] to [0,2,2] and applying an operation (for example, the formula of distance "sqrt ((x2-x1)^2+(y2-y1)^2)" and the result of that operation evaluate it with a guard), then compare the [1,2,3] to [1,4,5] and so end the list, then with [0 , 2.2] to [1,4,5] etc ...
I was thinking about taking (head i) and tail (head i) to compare, but do not know how to continue iterating comparisons
can you guys give me an idea about how i can do this? thank you
edit
what i need is this, with the first list of list i need to make another list of list's based on the distance formula and comparing the 3rd element of the list, for example
[[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...
Upvotes: 0
Views: 577
Reputation: 23955
This seems to produce your last example result:
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
Or with guards instead of if
and else
:
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)
Output:
*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]]
Upvotes: 2
Reputation: 4166
I'm not sure if I've understood you correctly, but perhaps this will help you figure something out:
.
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)
Outputs:
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)]
Upvotes: 1
Reputation: 3260
The question is really unclear, but it sounds like, at a fundamental level, you want to take each element of a list and compare it to all of the rest of elements in the list. Say we want to pair all of the elements in [1..3]
where order doesn't matter, i.e. we want the list:
`[(1, 2), (1, 3), (2, 3)]`
We can do this directly:
pairAll :: [a] -> [(a, a)]
pairAll [] = []
pairAll (x:xs) = map (\y -> (x, y)) xs ++ pairAll xs
Now pairAll [1..3] == [(1, 2), (1, 3), (2, 3)]
as desired. We can factor out the pairing function to get:
doStuffToAll :: (a -> a -> b) -> [a] -> [b]
doStuffToAll _ [] = []
doStuffToAll f (x:xs) = map (f x) xs ++ doStuffToAll f xs
And then pairAll = doStuffToAll (\x y -> (x, y))
.
Replace the lambda expression with your comparison function for lists (i.e. doStuffWithAll compareLists
), and that should do it, if I understand your question properly.
Upvotes: 4