您无法修改当前解决方案以删除第一个n 最小元素。为了能够移除第一个最小的n,您需要对整个列表进行总排序,以便确定哪些元素在n 最小区间内。
一个简单的解决方案是对列表进行排序并删除第一个 n 元素。但是,此解决方案不会保留原始顺序。
使用来自Data.List 的soryBy 和drop,您可以执行以下操作:
removeNSmallest :: Ord a => Int -> [(String, a)] -> [(String, a)]
removeNSmallest n xs = drop n $ sortBy (\(_, a) (_, b) -> compare a b) xs
正如@Micha Wiedenmann 指出的,您可以使用sortBy (comparing snd) 对元组进行排序。
一个小测试:
λ> removeNSmallest 1 [("String1", 50), ("String2", 600), ("String3", 10)]
[("String1",50),("String2",600)]
为了保留原始顺序,一种解决方案是为元组的第二个元素创建一个单独的有序列表。然后遍历原始列表,对于有序列表中的每个元素,从原始列表中删除一个。
如果您使用 drop 编写删除列表前 n 个元素的原始解决方案,则该解决方案的可读性会更高:
removeEle :: Int -> [a] -> [a]
removeEle n xs = drop n xs
或者如果你想使用显式递归:
removeEle :: Int -> [a] -> [a]
removeEle _ [] = []
removeEle 0 xs = xs
removeEle n x:xs = removeEle (n-1) xs