如何使用 foldl 删除列表的第 n 个元素?
How can I drop nth element of a list using foldl?
dropnth' :: [a] -> Int -> [a]
dropnth' xs n = foldl (\a b -> if (last a) == xs!!n then a else b ++ []) [head xs] xs
我试图使用 foldl 解决这个 "dropping every nth element of a list" 问题,但出现错误。我该怎么做?
错误:
a
想必是你已经决定不掉的元素。然后你应该决定是否删除,不是 a
的最后一个元素,而是 xs
中的下一个元素,大概是 b
.
b ++ []
大概是表示您决定不删除元素 b
,而是将其添加到列表 a
。这个其实写成a ++ [b]
.
这让我可以编写这段代码,它至少可以编译:
dropnth' :: Eq a => [a] -> Int -> [a]
dropnth' xs n = foldl (\a b -> if b == xs!!n then a else a ++ [b]) [head xs] xs
xs!!n
找到 xs
的第 n 个元素,并与它比较将决定某物的值是否等于它,而不是某物的位置。注意 Eq a
,它告诉我们我们正在比较列表值。 foldl
必须从某处获取条目的位置,例如从 zip [0..]
.
dropnth' :: [a] -> Int -> [a]
dropnth' xs n = foldl (\a (i, b) -> if mod i n == 0 then a else a ++ [b]) [head xs] (zip [0..] xs)
向列表末尾添加一个元素必须重建整个列表。从头开始构建列表会更有效率。但在这种情况下,我们甚至可以为我们的用例使用更专业的列表操作。
dropnth' :: [a] -> Int -> [a]
dropnth' xs n = [b | (i, b) <- zip [0..] xs, mod i n > 0]
请注意,我们现在也删除了初始元素。也许这就是你想要的?或者你可以 zip
和 [1..]
而不是将所有十字准线向左移动一位。
通常,像 Int -> [a] -> [a]
这样的类型签名会更好。
dropnth' :: [a] -> Int -> [a]
dropnth' xs n = foldl (\a b -> if (last a) == xs!!n then a else b ++ []) [head xs] xs
我试图使用 foldl 解决这个 "dropping every nth element of a list" 问题,但出现错误。我该怎么做?
错误:
a
想必是你已经决定不掉的元素。然后你应该决定是否删除,不是 a
的最后一个元素,而是 xs
中的下一个元素,大概是 b
.
b ++ []
大概是表示您决定不删除元素 b
,而是将其添加到列表 a
。这个其实写成a ++ [b]
.
这让我可以编写这段代码,它至少可以编译:
dropnth' :: Eq a => [a] -> Int -> [a]
dropnth' xs n = foldl (\a b -> if b == xs!!n then a else a ++ [b]) [head xs] xs
xs!!n
找到 xs
的第 n 个元素,并与它比较将决定某物的值是否等于它,而不是某物的位置。注意 Eq a
,它告诉我们我们正在比较列表值。 foldl
必须从某处获取条目的位置,例如从 zip [0..]
.
dropnth' :: [a] -> Int -> [a]
dropnth' xs n = foldl (\a (i, b) -> if mod i n == 0 then a else a ++ [b]) [head xs] (zip [0..] xs)
向列表末尾添加一个元素必须重建整个列表。从头开始构建列表会更有效率。但在这种情况下,我们甚至可以为我们的用例使用更专业的列表操作。
dropnth' :: [a] -> Int -> [a]
dropnth' xs n = [b | (i, b) <- zip [0..] xs, mod i n > 0]
请注意,我们现在也删除了初始元素。也许这就是你想要的?或者你可以 zip
和 [1..]
而不是将所有十字准线向左移动一位。
通常,像 Int -> [a] -> [a]
这样的类型签名会更好。