Mam listę ciągów znaków, czy można ją przekonwertować na listę elementów int?
npKonwertuj listę ciągów na listę int
["1","2"] -> [1,2]
Mam listę ciągów znaków, czy można ją przekonwertować na listę elementów int?
npKonwertuj listę ciągów na listę int
["1","2"] -> [1,2]
Dobrze
f :: [String] -> [Int]
f = map read
Nie?
Ogólna odpowiedź na takie pytania polega na podzieleniu zadania na części: [String] -> [Int]
wygląda na połączenie String -> Int
i [a] -> [b]
. Hoogle (połączone) daje pewne rezultaty dla obu, zobaczmy ...
$ hoogle 'string -> INT'
Test.HUnit.Base Etykieta :: String -> Węzeł błąd
Prelude: [Char] -> długość
Prelude :: [A] -> Int
długość Data.List :: [A] -> Int
Data.Char digitToInt :: Char -> Int
Data.Char ord :: Char -> Int
Debug.Trace trace :: String -> a -> a
Network.Buf ferType buf_fromStr :: BufferOp a -> String -> a
Network.Socket wysłać :: Socket -> String -> IO Int
Graphics.UI.GLUT.Callbacks.Window Char :: Char -> Key
Prelude odczytu :: Odczyt => String -> a
Text.Read czytać :: Odczyt => String -> a
Data.String fromString :: IsString a => String -> a
GHC.Exts fromString :: IsString a => String -> a
Control.Monad.Trans.Error strMsg :: błąd a => String -> a
Control.Monad.Error.Class strMsg :: błąd a => String -> a
. ..
Ugh, dużo śmieci. Możemy najpierw wyeliminować te z pakietów masz nic wspólnego z ...
błędzie Prelude :: [Char] -> długość
Prelude :: [a] -> int
długość Data.List :: [a] -> Int
Data.Char digitToInt :: Char -> Int
Data.Char ord :: Char -> Int
Prelude czytać :: Odczyt => String -> a
Tekst. Czytaj przeczytaj: Read a => String -> a
Data.String fromString :: IsString a => String -> a
Text.Printf printf :: PrintfType r => String -> r
error
brzmi prawie jak to, co chcesz. length
nie. digitToInt
? Brzmi nieźle - i działa w rzeczywistości, ale tylko z liczbami jednocyfrowymi. read
? Być może nie jest to nazwa, której się spodziewałeś, ale jeśli myślisz o tym, to jest to słuszne: konwersja łańcucha na coś bardziej znaczącego (jak liczba) jest jak czytanie jakiegoś tekstu.
Prawo, po drugiej stronie Hoogle daje nam coś chcemy aż przodu:
$ hoogle '[a] -> [b]'
Prelude map :: (a -> b) -> [a] -> [b]
Data.List map :: (a -> b) -> [a] -> [b]
Prelude concatMap :: (a -> [b]) - > [a] -> [b]
Data.List concatMap :: (a -> [b]) -> [a] -> [b]
Data.Maybe mapMaybe :: (a -> Maybe b) -> [a] -> [b]
Cykl wstępny e :: [a] -> [a]
Cykl Data.List :: [a] -> [a]
Prelude init :: [a] -> [a]
Data.List init :: [ a] -> [a]
Prelude odwrócić :: [a] -> [a]
Jak widać większość z tych funkcji są nazywane coś z "map", który nie może ponownie być nazwa spodziewałeś się - ale widocznie tak właśnie nazywa się ta operacja! Ten, którego szukasz, jest dość prosty.
Wreszcie, musimy połączyć te dwie funkcje. map
potrzebuje innej funkcji jako swojego pierwszego argumentu - cóż, to oczywiście read
! Więc wystarczy zastosować map
do read
. Następnym argumentem jest lista [a]
s: aha, już skończyliśmy!
Można to sprawdzić poprzez uruchomienie aż ghci:
Prelude>: t mapę czytać
mapie Czytaj :: Czytaj b => [String] -> [b]
Jest wciąż ten b
tutaj zamiast Int
, ale nieważne, że: b
może być dowolnym typem, który chcesz! - pod warunkiem, że ma instancję Read
. Int
posiada:
Prelude>: i Int
danych Int = GHC.Types.I # GHC.Prim.Int # - Zdefiniowane w `GHC.Types'
instancji ograniczony Int - Zdefiniowane w` GHC.Enum '
instancja Enum Int - Zdefiniowane w `GHC.Enum'
instancji Eq Int - Zdefiniowane w` GHC.Classes'
instancji Integral Int - Zdefiniowane w `GHC.Real”
instancji Num Int - Zdefiniowana w `GHC.Num '
instancja Ord Int - Zdefiniowana w` GHC.Classes'
instancja Odczytaj Int - Zdefiniowana w `GHC.Read '
instancja Real Int - Zdefiniowana w instancji` GHC.Real'
Pokaż Int - Zdefiniowana w `GHC.Show”
ta zawodzi:
map read ["1","2"]
[*Exception: Prelude.read: no parse
Sposobem na to jest:
map (read::String->Int) ["1","2"]
[1,2]
:: [Int]
Poza GHCI w pliki .hs byłoby:
let intList = map (read::String->Int) ["1","2"]
to działało! :) tnx – pier