2017-03-14 10 views
0

私は、リストの中の項目を、リストの中の "book"のような先行する要素に対する相対的な順序で番号付けしようとしています。Haskell:リスト内のアイテムに番号を付ける

myList=["book","book","title","author","title","book","title","book", "author"] 

私が持っているしたいと思います:

[book 1, book 2, title 2.1, author 2.1, title 2.2, book 3, title 3.1, book 4, author 4.1] 

カウントが新しい「本」満たされた後、「タイトル」と「著者」のための1で再起動します。 私はeazily本の番号を付けることができますが、私は書籍番号に応じて他の項目の番号を付ける方法がわかりません。

ので、私はこのようなリスト内包、内ファスナー結合しようとした:結果がタプルであるかどうかは関係ありません

[(1,"title"),(2,"author"),(3,"title"),(4,"title"),(5,"author")] 

zip [fst (head (zip[1..][x | x <- myList, x=="book"]))..][x | x <- myList, x=="title" || x=="author"] 

しかし、私が得たのですまたはリスト。

本当にありがとうございます。

おかげで、 オマール

答えて

2

あなたはカウント変数を追跡するための補助機能を使用することができます。

number xs = number' 0 0 xs 
number' n m (x:xs) | x == "book" = (x,n+1,0) : number' (n+1) 0 xs 
number' n m (x:xs) | otherwise = (x,n,m+1) : number' n (m+1) xs 
number' _ _ [] = [] 
+0

ありがとうございました!できます。フォローアップの質問として – omar

+0

。私はタプルのリストをmap(\(a、b、c) - > [a、b、c])[( "book"、1、0)のようなリストのリストに変換しようとしました。]そして、私は次のエラーメッセージが表示されます:(Num [Char])のインスタンスが使用されていません....文字列のタプルだけで変換が正常に動作するため、数値が原因です。どんな考え?おかげで再び – omar

+0

haskellのリストは同種であり、異なるタイプの混合をサポートしていません。 – rubystallion

0

リストを超える蓄積するための多くの機能があります。この場合、前の要素からの情報を引き継ぐ必要があることを除いて、mapのようなものが必要です。これを行う関数はscanl :: (s -> a -> s) -> s -> [a] -> [s]です。

浮動小数点数よりも一対の整数を積み上げた方がよいです。浮動小数点は不正確なので、望む以外の何かで終わる可能性があります。 s = (Int, Int)とし、ステップ関数を作成しましょう。我々は"book"を見ると

step :: (Int, Int) -> String -> (Int, Int) 
step (a, b) [email protected]"book" = (a + 1, 0 ) 
step (a, b) [email protected]"title" = (a , b + 1) 
step (a, b) [email protected]"author" = (a , b + 1) 
step x  _   = x 

我々は左整数に1を追加し、0に右の整数を設定します。 "title"または"author"が表示されたら、1を右の整数に追加し、左の整数を同じままにします。それ以外の場合は、両方の整数を同じにします。これは必要に応じて変更できます。

scanl step (0, 0) myList 
= [(0,0),(1,0),(2,0),(2,1),(2,2),(2,3),(3,0),(3,1),(4,0),(4,1)] 

最後に2つのことを行う必要があります。まず、scanlが最初の要素として初期状態を生成しますが、私たちはそれを望んでいません。 scanlは常に空でないリストを生成するため、tailまたはdrop 1tailは大丈夫ですが、多くの場合drop 1が好きです)で簡単に削除されます。次に、適切な文字列で各タプルを増やしたいとします。

zipWith (\s (a, b) -> (s, a, b)) <*> drop 1 . scanl step (0, 0) 

あなたは<*>に精通していない場合には、(この場合)(<*>) f g x = f x (g x)です。

\xs -> zipWith (\s (a, b) -> (s, a, b)) xs ((drop 1 . scanl step (0, 0)) xs) 
関連する問題