2012-02-12 8 views
1

私は、次のようなタプルの2つのリストを持っています:[(String,Integer)][(Float,Integer)]です。各リストには複数のタプルがあります。この関数はStringのリストを返す必要があるが、 - 第二のリスト内Floatを持つすべてIntegerについてはハスケル内のマップとフィルタ

、私はそのIntegerは、最初のリストにIntegerと一致し、それがない場合は、Stringを返すかどうかを確認する必要がありますs、つまり[String]となります。

私は既に、最初のリストの整数の比較のために、2番目のリストからIntegerのリストを返す関数を定義しました。

これは、「高次関数」を使用して解くことができます。 mapfilterでかなりの時間を費やしましたが、解決策が見つかりませんでした。

答えて

6

リストのリストはIntegersです。これをintsとしましょう。

ここでは、(String, Integer)リストをフィルタして、intsリスト内の対応する整数だけを含むようにリストし、次にこのリストをStringのリストに変換します。

これらの2つのステップはそれぞれfiltermapに対応します。

まず、フィルタリングする関数が必要です。この関数は(String, Integer)の組を取り、その整数がintsリストにある場合は返されます。したがって、タイプは次のとおりです。

check :: (String, Integer) -> Bool 

これを書くことはそれほど難しいことではありません。一度それを持っていれば、それによって最初のリストをフィルタリングできます。

次に、(String, Integer)のペアをStringに変換する関数が必要です。これには次のタイプがあります:

extract :: (String, Integer) -> String 

これもまた書きやすいでしょう。 (このような標準的な関数は実際には存在しますが、学習しているのであれば自信を持って調べることができます)。この関数を前のフィルタの結果にマップする必要があります。

解決策を得るために十分なヒントが得られたら幸いです。

+0

うわー、あなたはそれを信じられないほどうまく説明しました。私の講師よりもはるかに良い!ありがとう、これから私は解決策を見つけるのに約10分かかりました! – gdrules

2

この例では、問題を正確に記述することが重要であることが分かります。

関連する整数が2番目のリストに存在する最初のリストの文字列が必要です。

このような問題がある場合、ソリューションを小さなステップで実行することが重要です。ほとんどの場合、すぐに機能する関数を書き留めることはできませんが、これは多くの初心者が行うべきことです。

があなたの機能のために必要な型シグネチャを書くことから始め

  1. :問題の説明から、

    findFirsts :: [(String, Integer)] -> [(Float, Integer)] -> [String] 
    

    今、我々は、本質的に行うには二つのものを持っていることを、推測することができます(String、Integer)のリストを文字列のリストに変換する

  2. 必要な項目を選択します。したがって

、私達の機能の基本骨格は、次のようになります。

findFirsts sis fis = map ... selected 
    where 
     selected = filter isWanted sis 
     isWanted :: (String, Integer) -> Bool 
     isWanted (_,i) = .... 

あなたは空のスペースを記入する機能fstelemsndが必要になります。

サイドノート:私は個人的には、リストの理解度でこれを解決することをお勧めします。これは、マップとフィルタの組み合わせに比べてはるかに読みやすい(とにかく)コードです。

+0

寄付いただきありがとうございます、私はそれを感謝します:) – gdrules

1

問題の半分は、整数が1つの場合は文字列リストを取得することです。これを行うには様々な可能性があります。 filtermapを使用してください。あなたが持っている倍(ここでは[])開始値およびすべてのリスト要素で順次実行中の値を組み合わせて動作させるため

findAll x axs = foldr extract [] axs where 
    extract (a,y) runningList | x==y = a:runningList 
          | otherwise = runningList 

--usage: 
findAll 2 [("a",2),("b",3),("c",2)] 
--["c","a"] 

を、いずれかの左から:あなたが使用して両方の操作を組み合わせることができますが、「倍」 (foldl)または右側(foldr)から。ここでの操作はextractで、現在の要素の文字列を実行リストに追加するかどうかを決定するために使用します。

残りの半分は簡単です:(Float,Integer)リストから整数を取得する必要があります。そのすべてをfindAllとし、結果を結合します。

+0

ありがとう助けをたくさん:) – gdrules

関連する問題