Haskellタプルのn番目の要素を取得する必要があります。タプルは次のようになります:(3,5、 "String1"、 "String2"、 "String3"、 "String4"、 "String5"、 "String6"、 "String7"、 "String8"、 "String9"、 "String10 ")。この問題を解決するためのアイデアを教えていただけますか?ありがとう。
6 に答える
あなたが知っているかもしれないし知らないかもしれないので、fstとsndは2要素のタプルに対してのみ機能します。
fst' (a,b) = a
私の知る限り、あなたは自分で書く必要があります
get5th (_,_,_,_,a,_,_,_,_,_) = a
ご覧のとおり、独自のタイプを定義することをお勧めします。
あなたはパターンマッチングでそれを行うことができます。2値または3値のタプルと照合できるのと同じように、10値のタプルと照合できます。
let (_, _, _, _, _, _, _, _, _, x, _, _) = tuple in x
ただし、それをしたくない可能性があります。タプルからn番目の値を取得しようとしている場合は、ほぼ間違いなく間違ったタイプを使用しています。Haskellでは、長さの異なるタプルはタイプが異なり、基本的に互換性がありません。と同じようInt
に、そしてString
異なって(Int, Int)
おり(Int, Int, Int)
、また完全に異なっています。
n番目の要素を取得できるデータ型が必要な場合は、。のようなリストが必要です[String]
。リストを使用すると!!
、インデックス付けに演算子(0から始まる)を使用できるため、次のようにすることができます。
myList !! 9
10番目の要素を取得します。
あなたの例を考えると(Int, Int, [String])
、巨大なタプルではなく、のようなタイプが必要だと思います。これにより、2つの数値と任意の数の文字列を使用できるようになります。!!
上記の演算子を使用して、インデックスで文字列を取得できます。
タプルパッケージの選択関数を使用することをお勧めします。
タプルごとに1回だけこれを行う必要があり、一度にすべての要素が必要な場合は、次を使用できます。
let (x, y, s1, s2, s3, s4, s5, s6, s7, s8) = someTuple
in ...
値を直接使用します。
次のようなレコードタイプを使用する方がよいと思います。
data MyRec = MyRec {myrecfoo::Double, myrecbar::String, myrecbaz::String}
次に、レコードアクセサーを使用します。
baz = myrecbaz rec
ただし、タプルを使用したい/必要があり、フィールドが20未満の場合は、Control.Lens.Tupleを使用できます。
同じ問題の解決策を探していたときに、あなたの質問を見ました。「!!」を読みました 演算子は悪い解決策です。私は解決策を考えました:
たとえば、リスト内のタプルごとに3つの要素がある場合は、次のように実行できます。
nTuple :: [(a, a, a)] -> Integer -> Integer -> [a]
nTuple list group position = [ fst x | x <- (concat [ fst x | x <- (zip [(zip[t1, t2, t3][0..]) | (t1, t2, t3) <- list ] [0..]) , snd(x) == group ]) , snd(x) == position]
さて、いくつかのテストケース:
*Main> nTuple [("l","m","n"),("o","p","q"),("r","s","t")] 2 1
["s"]
*Main> nTuple [("l","m","n"),("o","p","q"),("r","s","t")] 0 2
["n"]
*Main> nTuple [("l","m","n"),("o","p","q"),("r","s","t")] 100 2
[]
*Main> nTuple [("l","m","n"),("o","p","q"),("r","s","t")] 2 100
[]
上記の関数のステップバイステップの説明:
1.要素を分割してインデックスを作成します。
[ zip[t1,t2,t3][0..] | (t1,t2,t3) <- [("l","m","n"),("o","p","q"),("r","s","t")]]
result: [[("l",0),("m",1),("n",2)],[("o",0),("p",1),("q",2)],[("r",0),("s",1),("t",2)]]
2.リストごとにインデックスを付けます。これで、グループと各グループ内のポジションができました。
zip [[("l",0),("m",1),("n",2)],[("o",0),("p",1),("q",2)],[("r",0),("s",1),("t",2)]] [0..]
result: [([("l",0),("m",1),("n",2)],0),([("o",0),("p",1),("q",2)],1),([("r",0),("s",1),("t",2)],2)]
3.グループを選択できます。たとえば、「snd(x)== 1」のグループ番号1(最初のグループは0)
[ fst x | x <- [([("l",0),("m",1),("n",2)],0),([("o",0),("p",1),("q",2)],1),([("r",0),("s",1),("t",2)],2)] , snd(x) == 1 ]
result: [[("o",0),("p",1),("q",2)]]
4.リストのリストがあります。タプルの単一のリストにタプルを連結する
concat [[("o",0),("p",1),("q",2)]]
result: [("o",0),("p",1),("q",2)]
5.最後に、インデックスによって要素を取得します。この例では、2番目の要素を取得します(最初の要素は「0」の位置です)
[ fst x | x <- [("o",0),("p",1),("q",2)] , snd(x) == 2]
result ["q"]