榆树 - 将文本文件解析为Html

时间:2015-08-08 08:14:33

标签: html parsing csv elm

我是榆树的新手(一般来说对FP很新)我在如何处理某些事情时遇到了一些麻烦。

我正在使用当前端口读取文本文件并将其传递给elm(index.html):

<script type="text/javascript">
  // Show the stamp module in the "elm-div" div.
  var div = document.getElementById('elm-div');
  var golf = Elm.embed(Elm.Golf, div, { reset:[], openFromFile: "" });

  var upload = document.getElementById('fileinput');

  upload.onchange = function (e) {
      reader = new FileReader();

      reader.onload = function (event) {
          data = event.target.result;
          //file's text data is sent to 'openfromfile' port
          golf.ports.openFromFile.send(data);
          }
      reader.readAsText(upload.files[0]);
      };
</script>

Golf.elm(到目前为止):

module Golf where

import Html exposing (Html, Attribute, text, toElement, div, input)
import Html.Attributes exposing (..)
import Color exposing (..)
import Signal exposing ((<~),(~))
import String

port reset : Signal ()   
port openFromFile : Signal String

getLines : Signal (List String)
getLines = String.lines <~ openFromFile

我无法考虑如何构建Golf.elm文件。我有CSV格式的文本数据(由','分隔),其中:

"Round Number", "Par", "steve", "kyle", "rick"
1, 3, 5, 8, 1
2, 5, 3, 7, 8
3, 4, 6, 5, 4
4, 3, 2, 4, 3
5, 2, 5, 7, 4

我想要做的是阅读CSV并显示一个html表格,其中每个玩家/回合的得分相对于标准杆数(得分=数字 - 标准杆)但事实上我开始没有记录常规模型格式,但Signal (List String)让我彻底迷失了。

我已将getLines通过端口发送回console.log,因此我知道我正在正确读取文件并从文本源正确生成Signal (List String)但我无处可去从这里开始

1 个答案:

答案 0 :(得分:3)

解释

您可以从类型开始:

type alias CSV = { headers : Maybe (List String)
                 , records : List  (List String)
                 }

你有:

getLines : Signal (List String)

但需要:

getCSV   : Signal CSV

使用核心Signal.map

map : (a -> result) -> Signal a -> Signal result

然后输入签名将是(a = List String,结果= CSV):

map0     : (List String -> CSV) -> Signal (List String) -> Signal CSV

缺少部分是:

parseCSV : List String -> CSV

将所有事物结合在一起:

getCSV : Signal CSV
getCSV = Signal.map parseCSV getLines

结果

-- ...

getCSV : Signal CSV
getCSV = Signal.map badParseCSV getLines

type alias CSV = { headers : Maybe (List String)
                 , records : List  (List String)
                 }

badParseCSV : List String -> CSV
badParseCSV xs =
  let parseLine = List.map (trimQuotes << String.trim)
              <<  String.split ","
      trimQuotes x = if String.startsWith "\"" x 
                     && String.endsWith "\"" x
                     then String.dropRight 1 <| String.dropLeft 1 x
                     else x
      records0 = List.map parseLine
              <| List.filter (\x -> not (String.isEmpty x))
              <| List.drop 1 xs
      headers0 = Maybe.map parseLine <| List.head xs
  in  { headers = headers0
      , records = records0}

view : CSV -> Html
view csv =
  let rows    = List.map (\xs -> Html.tr [] (cols xs)) csv.records
      cols xs = List.map col xs
      col  x  = Html.td [] [ text x]
      ths  xs = List.map (\x -> Html.th [] [text x]) xs
      headers = Maybe.withDefault [] <| Maybe.map ths csv.headers
  in Html.table [] [ Html.thead [] headers
                   , Html.tbody [] rows
                   ]

main : Signal Html
main = Signal.map view getCSV