我想知道如何在给定列表中返回第n对的第二个项目。所以我们有
header
因此,如果我们输入
nth :: Int -> [(Int,Int)] -> Int
它应该返回8,因为这是第三对的第二项。
这是我到目前为止所获得的,它不起作用...
nth 3 [(2,0),(1,4),(3,8)]
有人可以协助吗?
谢谢 山姆
答案 0 :(得分:2)
要填写到目前为止的内容:
nth :: Int -> [(Int,Int)] -> Int
nth n [] = error "??"
nth 0 (x:xs) = snd x
nth n (x:xs)
|n > 0 && n < length (x:xs) = nth (n-1) xs
(snd
函数仅返回一对的第二个元素)
但是,您可以尝试将!!
和snd
这些函数简单地组合在一起:
nth' :: Int -> [(Int,Int)] -> Int
nth' n xs = snd (xs !! n)
答案 1 :(得分:1)
您需要在列表的 tail 上递归。因此,您可以再次调用该函数,但要使用n-1
和列表的末尾。作为基本情况,然后检查索引是否为大小写,返回此大小写的第二个元素,返回该元组的第二个元素。不使用任何内置函数的实现,可能看起来像这样:
nth :: Int -> [(a, b)] -> b
nth _ [] = error "Index too large"
nth n _ | n <= 0 = error "Index too small"
nth 1 ((_, b):_) = b
nth n (_: xs) = nth (n-1) xs
但是实际上我们可以使用(!!) :: [a] -> Int -> a
,(.) :: (b -> c) -> (a -> b) -> a -> c
和snd :: (a, b) -> b
功能,因此可以这样写:
nth n = snd . (!! (n-1))
答案 2 :(得分:1)
您可以先将问题分解成小部分,然后进行工作,测试每个部分;你终于把它们放回去了。
InherTest
将以上3个放在一起即可得到:
-- 1. Pair each element with an index starting from 1 -> [(Int, (Int, Int))]
-- 2. Find the nth-index element -> Maybe (Int, (Int, Int))
-- 3. Get the 2nd element of the second element -> Int
答案 3 :(得分:0)
nth2nd :: Int -> [(Int,Int)] -> Int
nth2nd n xs = head [b | (i,(_,b)) <- zip [1..] xs, i==n]
是您所需要的。当然,此函数是部分函数,即如果n
大于列表的长度,则会导致错误;如果n
小于1,则将尝试遍历整个列表,并且然后导致错误(如果列表无限,则无限循环。)
通常不认为这是件好事。我们通常更喜欢用Maybe
来说明失败的可能性,从而使函数 total :
import Data.Maybe
nth2ndMaybe :: Int -> [(Int,Int)] -> Maybe Int
nth2ndMaybe n xs = listToMaybe [b | (i,(_,b)) <- zip [1..] xs, i==n]
尽管如此,它仍会在非肯定的n
上轰炸。添加警卫将有助于处理这种情况,最好通过显式返回Nothing
:
nth2ndMaybe n xs
| n < 1 = Nothing
| otherwise = ......