2016-10-11 4 views
0

Ich habe vor kurzem angefangen, Haskell zu lernen, und es fällt mir schwer herauszufinden, wie man Textdateien interpretiert.Haskell-Datei lesen und Werte finden

Ich habe folgende TXT-Datei:

ncols   5 
nrows   5 
xllcorner  809970 
yllcorner  169790 
cellsize  20 
NODATA_value -9999 
9 0 0 0 0 
0 1 0 0 0 
0 0 0 0 0 
0 0 0 0 0 
0 2 0 0 3 

Die ersten 6 Zeilen nur einige Informationen angezeigt werden ich brauche, wenn sie mit der Datei in einer GIS-Software arbeiten. Der eigentliche Deal beginnt, wenn ich versuche, mit den Zahlen in Haskell zu arbeiten.

Ich möchte Haskell anweisen, wo die Zahlen 9, 1, 2 und 3 sind und die Nummer der Zeile und Spalte, wo diese Zahlen tatsächlich sind, ausdrucken. In diesem Fall sollte Haskell drucken:

The value 9 is in row 1 and column 1 
The value 1 is in row 2 and column 2 
The value 2 is in row 5 and column 2 
The value 3 is in row 5 and column 5 

Ich habe versucht, die Lösung (oder zumindest ähnliche Methoden für Dateien zu interpretieren) zu finden in Tutorials und anderen Haskell Scripts ohne Erfolg, so würde jede Hilfe sehr geschätzt.

Antwort

3

Hier ist ein Beispiel für ein Skript zu tun, was Sie wollen. Beachten Sie, dass dies in seiner aktuellen Form nicht ordnungsgemäß fehlschlägt (aber da dies ein Skript ist, bezweifle ich, dass dies ein Problem ist). Stellen Sie sicher, dass am Ende Ihrer Datei ein abschließender Zeilenumbruch ist!

import Control.Monad (replicateM, when) 
import Data.Traversable (for) 
import System.Environment (getArgs) 

main = do 

    -- numbers we are looking for 
    numbers <- getArgs 

    -- get the key-value metadata 
    metadata <- replicateM 6 $ do 
    [key,value] <- words <$> getLine 
    return (key,value) 

    let Just rows = read <$> lookup "nrows" metadata 
     Just cols = read <$> lookup "ncols" metadata 

    -- loop over all the entries 
    for [1..rows] $ \row ->do 
    rawRow <- words <$> getLine 
    for (zip [1..cols] rawRow) $ \(col,cell) -> 
     when (cell `elem` numbers) 
     (putStrLn ("The value " ++ cell ++ " is in row " ++ show row ++ " and column " ++ show col)) 

es zu verwenden, es als Befehlszeilenargumente, die Zahlen übergeben Sie suchen, und dann füttern als Datendateieingabe.

$ ghc script.hs 
$ ./script 9 1 2 3 < data.txt 

Lassen Sie mich wissen, wenn Sie irgendwelche Fragen haben!

Ich war nicht wirklich sicher, ob Sie nur eine feste Reihe von Zahlen oder eine andere Zahl als Null suchen wollten. Als Ihre Frage nach dem ersten gefragt hat, habe ich das getan.

+0

Vielen Dank, Sie sind ein Lebensretter! Eine weitere Frage, wo genau sollte ich meine Daten und die Zahlen eingeben? Wenn ich zum Beispiel folgendes anwende: data <- getData "test.txt", wird nur ein Fehler zurückgegeben. – EvilHappyHippo

+0

Eine Beschreibung hinzugefügt. Die Datei wird als Standardeingabe erwartet, daher können einige Shell-Befehle den Tag speichern. – Alec

+0

Nochmals vielen Dank. Das hat mir sehr geholfen! Letzte Frage: Gibt es eine Möglichkeit, dies automatisch nach dem Erstellen des Skripts in GHCi zu tun? Prost! – EvilHappyHippo