如何使用列表推导将列表拆分为两半?
e.g。如果我有[1,1,2,2,3,3,4,4,5,5]
而我只想要[1,1,2,2,3]
到目前为止我的尝试:
half mylist = [r | mylist!r ; r <- [0..(#mylist div 2)] ] ||does not work
有什么想法吗?
[Nb:这实际上并不是Haskell,而是类似的。 !用于索引列表,#给出长度)
编辑::
好的,事实证明
half mylist = [r | r <- [mylist!0..mylist!(#mylist div 2)] ]
有效,但仅限于数字列表而非字符串。有线索吗?
答案 0 :(得分:8)
这与列表理解不太合适。列表推导是地图和过滤器(和拉链)的替代语法。拆分列表是一种折叠。
因此,您应该考虑采用不同的方法。 E.g。
halve :: [a] -> [a]
halve [] = []
halve xs = take (n `div` 2) xs
where n = length xs
拆分对于大型列表来说不是一个很好的操作,因为你先取长度(所以它总是 n + n / 2 操作列表。)更适合具有 O(1)长度和拆分的类似数组的类型。
答案 1 :(得分:4)
另一种可能的解决方案,使用布尔守卫:
half xs = [x | (x,i) <- zip xs [1..], let m = length xs `div` 2, i <= m]
但正如Don Stewart所说,列表理解并不是这项工作的正确工具。