How to select items from one list depending on another

Hi, I have this problem at hand - Given two lists list1 = [0,1,2,0,1,4] list2 = [1,2,3,4,5,6] I need to take items from the second list only when the corresponding item in list1 is non-zero. list3 = map snd $ filter takeValid $ zip list1 list2 where takeValid (a,b) = a /= 0 Is there a shorter way? -- Regards, Kashyap

2010/11/10 C K Kashyap
Hi, I have this problem at hand -
Given two lists
list1 = [0,1,2,0,1,4]
list2 = [1,2,3,4,5,6] I need to take items from the second list only when the corresponding item in list1 is non-zero.
Another wayOne way to do it, although not shorter : list3 = catMaybes $ zipWith (\a b -> if a > 0 then Nothing else Just b) list1 list2 David.

On Wednesday 10 November 2010 16:13:39, David Virebayre wrote:
2010/11/10 C K Kashyap
: Hi, I have this problem at hand -
Given two lists
list1 = [0,1,2,0,1,4]
list2 = [1,2,3,4,5,6] I need to take items from the second list only when the corresponding item in list1 is non-zero.
Another wayOne way to do it, although not shorter :
list3 = catMaybes $ zipWith (\a b -> if a > 0 then Nothing else Just b) list1 list2
The function you zip with is \a b -> guard (a /= 0) >> return b, pointfree: (. return) . (>>) . guard . (/= 0) using the MonadPlus instance of Maybe. One could use any MonadPlus with a function [m a] -> [a] removing the mzeros, like catMaybes for Maybe, concat for []: import Control.Monad (guard) list3 = concat $ zipWith ((. return) . (>>) . guard . (/= 0)) list1 list2 but I wouldn't say that's better than list3 = map snd . filter ((/= 0) . fst) $ zip list1 list2 It's not shorter anyway.
David.

If only ParallelListComphttp://hackage.haskell.org/trac/haskell-prime/wiki/ParallelListCompsupported filters. list3 = [ b | a <- list1 | b <- list2 , a /= 0 ] But it doesn't, so this is an entirely unnecessary post :) Best, -- Ozgur Akgun

Thank you folks ... The best thing I like about Haskell is the wonderful mailing list :) -- Regards, Kashyap

2010/11/10 C K Kashyap
Hi, I have this problem at hand -
Given two lists
list1 = [0,1,2,0,1,4]
list2 = [1,2,3,4,5,6]
I need to take items from the second list only when the corresponding item in list1 is non-zero.
list3 = map snd $ filter takeValid $ zip list1 list2 where takeValid (a,b) = a /= 0
Is there a shorter way?
You can use list comprehenison and pattern matching here: list3 = [xs | (0, xs) <- zip list1 list2]

On Wed, Nov 10, 2010 at 16:08, Alexey Levan
2010/11/10 C K Kashyap
: Hi, I have this problem at hand -
Given two lists
list1 = [0,1,2,0,1,4]
list2 = [1,2,3,4,5,6]
I need to take items from the second list only when the corresponding item in list1 is non-zero.
list3 = map snd $ filter takeValid $ zip list1 list2 where takeValid (a,b) = a /= 0
Is there a shorter way?
You can use list comprehenison and pattern matching here:
list3 = [xs | (0, xs) <- zip list1 list2]
Or, since the OP asked for the "opposite": [b | (a, b) <- zip list1 list2, a /=0 ] /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus@therning.org Jabber: magnus@therning.org http://therning.org/magnus identi.ca|twitter: magthe

Aren't the list comprehension approach exponential in complexity - whereas the others linear? -- Regards, Kashyap

On Wed, Nov 10, 2010 at 09:45:43PM +0530, C K Kashyap wrote:
Aren't the list comprehension approach exponential in complexity - whereas the others linear?
No, they have exactly the same complexity. The list comprehension simply desugars into something very similar to the other solutions anyway. -Brent
participants (7)
-
Alexey Levan
-
Brent Yorgey
-
C K Kashyap
-
Daniel Fischer
-
David Virebayre
-
Magnus Therning
-
Ozgur Akgun