问题
I'm really not a star with regular expressions, especially with Haskell and even after reading some tutos.
I have a list of numbers like this:
let x = [1, 2, 3.5]
My goal is to have the string "1.0 2.0 3.5"
from this input.
My idea was to use regular expressions. But the way I use is tedious. First, I do
let xstr = show x
Then I remove the first bracket like this:
import Text.Regex
let regex1 = mkRegex "\\["
let sub1 = subRegex regex1 xstr ""
-- this gives "1.0,2.0,3.5]"
Then I remove the second bracket similarly:
let regex2 = mkRegex "\\]"
let sub2 = subRegex regex2 sub1 ""
Finally I remove the commas and replace them with white spaces:
let regex3 = mkRegex ","
let sub3 = subRegex regex3 sub2 " "
This gives "1.0 2.0 3.5"
, as desired.
Please do you have a better way ?
I always have lists with 3 elements, so this approach is not irrealistic, but it is tedious and not elegant. I even don't know how to delete the two brackets in one shot.
回答1:
map
will take a function and apply it to each element of a list, and intercalate will position something between every element of a list.
import Data.List
stringify :: Show a => [a] -> String
stringify = intercalate " " . map show
Sample use:
> stringify [1, 2, 3.5]
"1.0 2.0 3.5"
The idea is to keep the data in a computer-friendly form for as long as possible. Your approach immediately stringifies the whole thing, then tries to manipulate something that should really be treated as a list of integer as a string, which leads to some messy workarounds, as you've already seen.
It may also be a good exercise to do this by hand. map
and intercalate
are both fairly easy to implement with just recursion in Haskell, and doing so can be useful practice.
回答2:
This did just not seem too obvious but, goodness, I finally thought to try 'show' for the floating point numbers which were very easy to generate. In fact, Haskell converts all numbers of an ostensibly mixed type list to the highest common type. In the case of let [1,2,3,4.5] produces [1.0,2.0,3.0,4.5] just by itself. I should have guessed. I found two quick ways to generate the floating point strings.
concat [show fl ++ " "| fl <- [1,2,3,4.5]]
or
concat $ map (\st -> show st + " ") [1,2,3,4.5]
These, of course, can easily be parameterized. I do love concat. It is so very versatile. There is a trailing space which is easily removed with an "init $ ' before concat.
Then, of course, after a few minutes after posting this, I tried
tail . init $ show [1,2,3,4.5]
and it worked. haskell is just too cool. But, also of course, my bad. This last bit produces a string but the numbers do not have space between them. There are commas between them :(
来源:https://stackoverflow.com/questions/49398374/extract-numbers-as-strings-from-list-of-numbers