2012-10-28 137 views
0

我必須聲明如下(第一個參數的函數cca(列表),第二個參數是B(名單也一樣),它應該返回3號列表:列表操作

cc :: [(String, String)] -> [(String, String)] -> [(String, String)] 
cc a b = do 

例子:

a = [("aaa", "xxx"), ("bbb", "xxx")] 
b = [("xxx", "ccc"), ("xxx", "ddd")] 
c should be [("aaa", "ccc"), ("aaa", "ddd"), ("bbb", "ccc"), ("bbb", "ddd")] 

c是和的a組成b其中每個a雙第二「指數」是第一b雙「索引」。 所以a (「aaa」,「xxx」)對的第二個「索引」是「xxx」,其定義爲b(「xxx」,「ccc」)第一個「索引」。關於我們在返回列表中創建(添加)這個新對(「aaa」,「ccc」)。

問題是如何在Haskell中做到這一點? :)

最好的問候!

回答

4

以最簡單的方法做到這一點是一個列表理解,

cc a b = [(u,x) | (u,v) <- a, (w,x) <- b, v == w] 

我們根據條件與b和濾波器的所有元素配對的a所有元素,從組裝的部件的結果。

+0

這很好用:)只適用於情況cc [(「a」,「b」),(「a」,「d」),(「a」,「e」)] [ (「b」,「c」),(「d」,「c」)]它返回dublicates [(「a」,「c」),(「a」,「c」)]。我們怎樣才能刪除dublicates? – werd

+3

刪除重複項的最少代碼是使用'Data.List'中的'nub'。因爲只需要一個'Eq'實例,所以它的複雜度是二次的,但是,如果你想要更好的複雜性並且有一個'Ord'實例,'import Data.Set'和'Data.Set.toList。 Data.Set.fromList'刪除O(n * log n)中的重複項,但不考慮原始列表中元素的順序。如果你想讓O(n * log n)保持原來的順序,這有點複雜。 –

+0

太棒了!非常感謝 ;) – werd

3

使用列表理解,從兩份名單抓住對所有組合,與第一對的第二個元素等於第二對的第一個元素的條件:

[(x, z) | (x, y1) <- a, (y2, z) <- b, y1 == y2] 
+0

謝謝 - 這個工程。 Daniel的回答是一樣的想法 – werd

0
import Control.Applicative 

c = (,) <$> (fst.unzip) a <*> (snd.unzip) b 

-- or -- 

c = liftA2 (,) (fst $ unzip a) (snd $ unzip b)