如何从Haskell中的10元组中获取第n个元素?

时间:2013-03-21 21:15:43

标签: haskell tuples

我必须在Haskell元组中获得第n个元素。而元组是这样的: (3,5, “字符串1”, “String2的”, “STRING3”, “串,4”, “STRING5”, “String6”, “String7”, “String8”, “String9”, “String10”)。你能给我一个想法,以便我能解决这个问题吗? 感谢。

6 个答案:

答案 0 :(得分:39)

你可以用模式匹配来做到这一点。就像你可以匹配两个或三个值的元组一样,你可以匹配一个十值元组。

let (_, _, _, _, _, _, _, _, _, x, _, _) = tuple in x

但是,您可能想要这样做。如果你试图从元组中获取第n个值,那么你几乎肯定使用了错误的类型。在Haskell中,不同长度的元组是不同的类型 - 它们从根本上是不兼容的。就像IntString不同,(Int, Int)(Int, Int, Int)也完全不同。

如果你想要一个可以获得第n个元素的数据类型,你需要一个列表:类似[String]。使用列表,您可以使用!!运算符进行索引(从0开始),因此您可以这样做:

myList !! 9

获得第10个元素。

鉴于你的例子,我怀疑你想要一个像(Int, Int, [String])这样的类型而不是一个巨大的元组。这将让你有两个数字和任意数量的字符串;您可以使用上面的!!运算符按索引获取字符串。

答案 1 :(得分:27)

你可能知道或者可能不知道fst和snd只适用于2元素元组,即

fst' (a,b) = a

据我所知,你必须自己编写

get5th (_,_,_,_,a,_,_,_,_,_) = a

如您所见,您可能想要定义自己的类型。

答案 2 :(得分:21)

答案 3 :(得分:3)

如果每个元组只需要执行一次,并且您需要同时使用所有元素,则只需使用

count

并直接使用这些值。

答案 4 :(得分:1)

我认为您最好使用记录类型,例如:

data MyRec = MyRec {myrecfoo::Double, myrecbar::String, myrecbaz::String}

然后使用记录访问器:

baz = myrecbaz rec

但是如果您想/需要坚持使用元组并且字段少于 20 个,您可以使用 Control.Lens.Tuple

答案 5 :(得分:-2)

当我在寻找同一问题的解决方案时,我已经看到了你的问题。我看过“!!”运营商是一个糟糕的解决方我想到了一个解决方案:

例如,如果列表中的每个元组有三个元素,则可以执行此操作:

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.Split元素并放一个索引:

[ 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.我们可以选择一个组。例如,组号1(第一组是0),“snd(x)== 1”

[ 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.最后,我们按索引获取元素。在这个例子中,我们得到第二个元素(第一个元素是“0”位置)

[ fst x | x <- [("o",0),("p",1),("q",2)] , snd(x) == 2]

result ["q"]