2

我正在尝试解决前一年的一个旧的中期问题,但我在这个问题上遇到了很多麻烦。

使用列表推导,实现一个具有以下类型的函数:

collectSecond :: [[Int]] -> [Int]

这样 (collectSecond xs) 返回一个列表,其中包含 xs 的列表成员的第二个元素,长度小于 2 的列表成员除外。例如:

collectSecond [[1,2,3], [4], [], [5,6]] ~> [2,6]
collectSecond [[1], [], [2]] ~> []
collectSecond [] ~> []

对此的任何帮助将不胜感激。

4

2 回答 2

4

您可以在列表推导中使用模式匹配来获取第二个元素,如下所示:

collectSecond xs = [x2 |  x1:x2:rest <-  xs]

这里 x2 匹配 xs 包含的每个列表的第二个元素(如果有)。

Prelude> collectSecond [[1,2,3], [4], [], [5,6]]
[2,6]

如果没有第二个元素,则不会将任何元素添加到该子列表的列表中。例如,参见上面示例中的 [4] 和 []。

于 2013-02-22T03:48:26.830 回答
1

使用基本递归实现也很简单:

collectSecond ((x0:x1:_):ys) = x1:(collectSecond ys)
collectSecond (_:ys)         = collectSecond ys
collectSecond []             = []

(这里我们单独处理每个元素,如果有第二个元素,则将其添加到我们正在创建的列表中,如果没有第二个元素则跳过它)

你也可以使用concatMap

collectSecond xs = concatMap seconds xs
    where seconds (x0:x1:_) = [x1]
          seconds _         = []
于 2013-02-22T18:41:18.350 回答