将给定值的列表分解为子列表列表
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
.
导入 unfoldr
和 toList
这是您使用累加器的修改版本 - 除了 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
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
.
unfoldr
和 toList
这是您使用累加器的修改版本 - 除了 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