2017-02-10 11 views
0

2つのペアのリストをマージする関数を作成しました。この場合、各要素には文字と数値が含まれています。一致する要素のリストをマージする

mergeTupleList [] blist = blist 
mergeTupleList alist [] = [] 
mergeTupleList (a:ab:as) (b:bn:bs) = 
    if ab == b 
     then a:[] ++ bn:[] ++ mergeTupleList (a:ab:as) (bs) 
     else [] ++ mergeTupleList (as) (b:bn:bs) 

listA = [('a',1),('b',1),('a',2),('b',1)] 
listZ = [('b',1),('z',1),('b',1),('z',2)] 

「他」の場合には(B:BN:BS)がいるようだそれは、その後によってフィルタリングされていますので、最初にロードされた全ペアのリストが、短いバージョン(BS)ではありません' 調子。 元の(b:bn:bs)リストをこの関数に送信する方法を探しています。

入出力:

*Main> mergeTupleList ListA ListZ 
[('a',1),('z',1),('a',1),('z',2)] 

期待出力:明確化のため

[('a',1),('z',1),('a',1),('z',2),('a',2),('z',1),('a',2),('z',2)] 

はおそらくマージ適切単語ではありません。元のListZに存在するListAのすべての(2番目の)要素に対して、それに続く要素を書き込みます。

もう一つの例:

ListA = [1,0,3,0] 
ListZ = [0,8,0,9] 

*Main> mergeTupleList listA listZ 
[1,8,1,9] 

予想される出力: [1,8,1,9,3,8,3,9]

+1

機能を正確に説明してください。与えられた 'listA'と' listZ'で期待される出力は、2つのリストをマージすることで期待されるものではありません。 – Michail

+0

おそらく合併は適切な言葉ではありません。元のListZに存在するListAのすべての(2番目の)要素に対して、それに続く要素を書き込みます。 – Xui

+1

これはおそらく質問自体に編集する必要があります。 – Michail

答えて

1

私はあなたのためのソリューションのシリーズを持っています。まず、次のようにして目的の出力が生成されます。私はこれが指定されたと思うが、mergeTupleList' はもはや最初の行にbListを返さないことに注意してください。期待通りのパフォーマンスではありませんでしたが、あなたの記述は私があなたが望んでいると信じるように導きます。このソリューションへ

秘密は全体bsリストについては、次のabペアを評価する前に、全体bsリストを消費し、最初のa:abのためのすべてのtuplingを行いサブ関数tupleAB、が含まれていることです。

mergeTupleList' [] _ = [] 
mergeTupleList' alist [] = [] 
mergeTupleList' (a:ab:as) bbnbs = 
    let 
    tupleAB (b:bn:bs) = 
     if ab == b 
     then a:[] ++ bn:[] ++ tupleAB bs 
     else [] ++ tupleAB bs 
    tupleAB _ = [] 
    in tupleAB bbnbs ++ mergeTupleList' as bbnbs 

次に、上記の解決策は、いくつかのダングリングcase式を有する:[] ++

mergeTupleList'' [] _ = [] 
mergeTupleList'' alist [] = [] 
mergeTupleList'' (a:ab:as) bbnbs = 
    let 
    tupleAB (b:bn:bs) = 
     if ab == b 
     then a : bn : tupleAB bs 
     else tupleAB bs 
    tupleAB _ = [] 
    in tupleAB bbnbs ++ mergeTupleList'' as bbnbs 

いたずらすべてのこれらのわずかなクリーンアップです。リストの1つに番号が付けられていない場合、私たちは何をしますか?最初の2つの項をそれぞれペアにすると、(ペアの)ペアのリストが得られます。この変換関数はリストを変更します。

pairListCvt :: [a] -> [(a,a)] 
pairListCvt (a:b:cs) = (a,b) : pairListCvt cs 
pairListCvt (a:[]) = [] --maybe should be error? 
pairListCvt _ = [] 

listACvt = pairListCvt listA 
listZCvt = pairListCvt listZ 

ここでもまた、書き直すと、あまり一致しないパターンがあり、エラーが発生する可能性は低くなります。これは、安全性を提供するタイプを選択する例です。タイプの安全性。

mergeTupleList''' [] _ = [] 
mergeTupleList''' alist [] = [] 
mergeTupleList''' ((a,ab):as) bbnbs = 
    let 
    tupleAB ((b,bn):bs) = 
     if ab == b 
     then (a , bn) : tupleAB bs 
     else mergeTupleList''' as ((b,bn):bs) 
    tupleAB _ = [] 
    in tupleAB bbnbs ++ mergeTupleList''' as bbnbs 

次へ]を、私たちはblistから条件を作成するためにalistに各用語を使用しているので、 私はここにmapを使用しています。

mergeTupleList'''' as bbns = 
    let 
    tupleAB ((b,bn):bs) (a,ab) = 
     if ab == b 
     then (a, bn) : tupleAB bs (a,ab) 
     else tupleAB bs (a,ab) 
    tupleAB [] _ = [] 
    in concat $ map (tupleAB bbns) as 

最後に、インナーtupleABfoldとして処方することができます。リストの要素ごとの分解を通じてデータ構造を段階的に構築するもの。その倍のコアロジックは今やfに保持されています。

mergeTupleList''''' as bbns = 
    let 
    tupleAB bs aab = foldr (f aab) [] bs 
    f (a,ab) (b,bn) acc 
     | ab == b  = (a,bn) : acc 
     | otherwise  = acc 
    in concat $ map (tupleAB bbns) as 

私は、バインディングをスタイリッシュにするためにバインディングを使用する方が好きです。 Alghouthには、私がその選択に関して理解していないメモリパフォーマンスの問題があります。

mergeTupleListW as bbns = concat $ map (tupleAB bbns) as 
    where 
    tupleAB bs aab = foldr (f aab) [] bs 
    f (a,ab) (b,bn) acc 
     | ab == b  = (a,bn) : acc 
     | otherwise  = acc 

エクストラクレジット彼はリストモナドとして書かれた関数です。

mergeTupleListM as bbns = 
    do a <- as 
    tupleAB bbns a 
    where 
    tupleAB bs aab = foldr (f aab) [] bs 
    f (a,ab) (b,bn) acc 
     | ab == b  = (a,bn) : acc 
     | otherwise  = acc 
+0

ありがとう、あなたは私をもう一度救った!実際に私は '' [:] ++ ' – Xui

0

この質問は既に回答済みですが、コメントの助けを借りて私が考え出したのはここです。 最初に、groupByTwo関数を作成して、2つの要素を含むリストの中でlistAを中断します。

groupByTwo [] = [] 
groupByTwo list = 
(take 2 list) : (groupByTwo (drop 2 list)) 

その後、我々はリストのリストの各要素に対して簡単なmergeTupleListを実行するためのmergeTupleList'関数を作成します。

mergeTupleList' [] _ = [] 
mergeTupleList' (a:as) list2 = 
    mergeTupleList a list2 ++ mergeTupleList' as list2 

最後に、第3の機能groupTupleMergeと呼ばれ、より使いやすくなっています。

groupTupleMerge list1 list2 = 
    mergeTupleList' (groupByTwo list1) list2 
関連する問題