将给定值的列表分解为子列表列表

Breaking a list on a given value into a list of sublists

multipleLists 函数需要从列表中删除给定的值,return 列表的列表。这些子列表对每个元素进行分组,直到它达到需要删除的值。当这种情况发生时,一个新的子列表开始。

input:           multipleLists 'b' "abcabc"
expected output: ["a","ca","c"]
actual output:   ["a","c","a","c"]

input:           multipleLists 1 [0,1,2,3,4,1,3,4]
expected output: [[0],[2,3,4],[3,4]]
actual output:   [[0],[2],[3],[4],[3],[4]]

我认为 otherwise 的情况有问题,但我有点卡住了。

这是我的代码:

multipleLists :: Eq a => a -> [a] -> [[a]]
multipleLists value list = case list of 
    [] -> [] 
    [x] -> [[x]]
    x:xs 
        | value == x -> multipleLists value xs 
        | otherwise ->  [x] : (multipleLists value xs)
multipleListsAllowEmpty value list = 
    let (beginning, end) = break (value ==) list
    in beginning : case end of
        [] -> []
        (_:xs) -> multipleListsAllowEmpty value xs

multipleLists value = filter (not . null) . multipleListsAllowEmpty

在这里,我们从 Data.List.

导入 break

我们可以用

更简洁地表达multipleListsAllowEmpty
maybeTail [] = Nothing
maybeTail (_:xs) = Just xs

multipleListsAllowEmpty value = 
    toList . unfoldr (fmap maybeTail . break (value ==))

我们从 Data.List.NonEmpty.

导入 unfoldrtoList

这是您使用累加器的修改版本 - 除了 reverse(您可以通过改变累加器的累积方式将其删除)外,它不使用任何外部的东西:

multipleLists :: Eq a => a -> [a] -> [[a]]
multipleLists value = go []
  where
  go [] [] = []
  go [] (x:xs)
    | x == value = go [] xs
    | otherwise = go [x] xs
  go acc [] = [reverse acc]
  go acc (x:xs)
    | x == value = reverse acc : go [] xs
    | otherwise = go (x:acc) xs

你的例子(见我上面的评论):

> multipleLists 'b' "abcabc"
["a","ca","c"]

> multipleLists (1 :: Int) [0,1,2,3,4,1,3,4]
[[0],[2,3,4],[3,4]]

multipleLists 0 [0, 0] 的预期值是多少?

[]还是[[]]还是[[], []]

这里有两种不同的解决方案,它们都基于正确的折叠。

splitList :: Eq a => a -> [a] -> [[a]]
splitList x = tail . foldr sx [[]] . (x:)
  where
    sx y ws@(zs:zss) | y == x    = [] : ws
                     | otherwise = (y:zs) : zss

multipleLists :: Eq a => a -> [a] -> [[a]]
multipleLists x = filter (not . null) . foldr sx [[]] . (x:)
  where 
    sx y ws@(zs:zss) | y == x    = [] : ws
                     | otherwise = (y:zs) : zss