简体   繁体   English

Haskell:从字符串列表中删除空格

[英]Haskell: Deleting white space from a list of strings

The question is: Write a function that will delete leading white space from a string. 问题是:编写一个将从字符串中删除前导空格的函数。 Example: cutWhitespace [" x","y"," z"] Expected answer: ["x","y","z"] 示例: cutWhitespace [" x","y"," z"]预期答案: ["x","y","z"]

Heres what I have: 继承人我所拥有的:

cutWhitespace (x:xs) = filter (\xs -> (xs /=' ')) x:xs

This returns ["x", " y"," z"] when the input is [" x"," y", " z"] . 这将返回["x", " y"," z"]当输入为[" x"," y", " z"] Why is it ignoring the space in the second and third string and how do I fix it? 为什么忽略第二和第三个字符串中的空格,我该如何解决?

We are allowed to use higher-order functions which is why I implemented filter. 我们被允许使用高阶函数,这就是我实现过滤器的原因。

The reason the OP cutWhitespace function only works on the first string, is that due to operator precedence, it's actually this function: OP cutWhitespace函数仅对第一个字符串起作用的原因是由于运算符优先级,它实际上是这个函数:

cutWhitespace (x:xs) = (filter (\xs -> (xs /=' ')) x) : xs

Here, I've put brackets around most of the body to make it clear how it evaluates. 在这里,我将括号放在身体的大部分周围,以明确它的评估方式。 The filter is only applied on x , and x is the first element of the input list; filter仅应用于xx是输入列表的第一个元素; in the example input " x" . 在示例输入" x"

If you filter " x" as given, you get "x" : 如果您按照给定的方式过滤" x" ,则会得到"x"

Prelude> filter (\xs -> (xs /=' ')) " x"
"x"

The last thing cutWhitespace does, then, is to take the rest of the list ( [" y", " z"] ) and cons it on "x" , so that it returns ["x"," y"," z"] . cutWhitespace的最后一件事就是cutWhitespace列表的其余部分( [" y", " z"] )并将其收入"x" ,以便它返回["x"," y"," z"]

In order to address the problem, you could write the function with the realisation that a list of strings is a nested list of characters, ie [[Char]] . 为了解决这个问题,你可以编写函数,实现字符串列表是一个嵌套的字符列表,即[[Char]]

As a word of warning, pattern-matching on (x:xs) without also matching on [] is dangerous, as it'll fail on empty lists. 作为警告,在(x:xs)上进行模式匹配而不在[]上匹配是危险的,因为它在空列表上会失败。

The question you asked, on how to delete leading whitespace from a string, you can do by simply doing dropWhile on a string: 关于如何从字符串中删除前导空格的问题,您可以通过简单地对字符串执行dropWhile来完成:

deleteLeadingWhitespace = dropWhile (\c -> c == ' ')

though you should be more clever if you consider other things "whitespace". 如果你考虑其他事情“空白”,你应该更聪明。 You could use the "isSpace" function defined in Data.Char for example. 例如,您可以使用Data.Char中定义的“isSpace”函数。

From your sample data, it looks like you are really trying to do this for a list of strings, in which case you can map the dropWhile over your array: 从您的示例数据看,您似乎正在尝试为字符串列表执行此操作,在这种情况下,您可以将dropWhile映射到数组:

map deleteLeadingWhitespace

The filter approach you are taking is a little bit dangerous, because even if you had it doing what you think it should, it would be deleting all the spaces, not just the leading ones. 你正在采取的过滤方法有点危险,因为即使你按照你认为应该做的那样,它也会删除所有空格,而不仅仅是前导空格。

Instead of writing a custom function that checks if a character is whitespace, I would advice to use isSpace :: Char -> Bool . 我建议使用isSpace :: Char -> Bool ,而不是编写一个检查字符是否为空格的自定义函数。 This function does not only returns True for a space ( ' ' ), but for a new line ( '\\n' ), a carriage return ( '\\r' ), a tab ( '\\t' ), a vertical tab ( '\\v' ) and form feed ( '\\f' ) as well. 此函数不仅返回空格( ' ' )的True ,而且返回新行( '\\n' ),回车符( '\\r' ),制表符( '\\t' ),垂直制表符( '\\v' )和换页( '\\f' )。 Usually it is better to work with such functions since the odds of forgetting certain cases is lower. 通常最好使用这些功能,因为忘记某些情况的几率较低。

We can thus remove the spacing of a single string with: 因此,我们可以删除单个字符串的间距:

dropWhile isSpace

Where we thus dropWhile in such way that all chacters where isSpace . 因此,在哪里我们dropWhile以这样的方式,所有chacters其中isSpace

We can then perform a mapping with this filter to filter the spaces out of all the strings, like: 然后,我们可以使用此过滤器执行映射,以过滤所有字符串中的空格,例如:

import Data.Char(isSpace)

cutWhitespace = map (dropWhile isSpace)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM