2
-module(solarSystem).

-export([process_csv/1, is_numeric/1, parseALine/2, parse/1, expandT/1, expandT/2,
         parseNames/1]).

parseALine(false, T) ->
    T;
parseALine(true, T) ->
    T.

parse([Name, Colour, Distance, Angle, AngleVelocity, Radius, "1" | T]) ->
    T;%Where T is a list of names of other objects in the solar system
parse([Name, Colour, Distance, Angle, AngleVelocity, Radius | T]) ->
    T.

parseNames([H | T]) ->
    H.

expandT(T) ->
    T.

expandT([], Sep) ->
    [];
expandT([H | T], Sep) ->
    T.

% https://rosettacode.org/wiki/Determine_if_a_string_is_numeric#Erlang
is_numeric(L) ->
    S = trim(L, ""),
    Float = (catch erlang:list_to_float(S)),
    Int = (catch erlang:list_to_integer(S)),
    is_number(Float) orelse is_number(Int).

trim(A) ->
    A.

trim([], A) ->
    A;
trim([32 | T], A) ->
    trim(T, A);
trim([H | T], A) ->
    trim(T, A ++ [H]).

process_csv(L) ->
    X = parse(L),
    expandT(X).

问题是它会process_csv/1在我的模块中调用函数 a mainL将是这样的文件:

[["name "," col"," dist"," a"," angv"," r "," ..."],["apollo11 ","white"," 0.1"," 0"," 77760"," 0.15"]]

或者像这样:

["planets ","earth","venus "]

或者像这样:

["a","b"]

我需要显示如下:

apollo11 =["white", 0.1, 0, 77760, 0.15,[]];
Planets =[earth,venus]
a,b
[[59],[97],[44],[98]]

我的问题是,无论怎么修改,都只能显示一部分,没有符号。列表不能分割,所以我找不到方法。另外,由于 Erlang 是一种小众编程语言,我什至在网上都找不到示例。那么,任何人都可以帮助我吗?非常感谢。另外,我被限制使用递归。

4

1 回答 1

0

我认为第一个问题是很难将您试图实现的目标与您的代码迄今为止所说的联系起来。因此,此反馈可能不是您正在寻找的,但可能会提供一些想法。
让我们将问题构造成共同的元素:(1)输入,(2)过程,和(3)输出。

  1. 输入
    您提到 L 将是一个文件,但我假设它是文件中的一行,其中每一行可以是 3(三)个样本之一。在这方面,样本也没有一致的模式。
    为此,我们可以构建一个函数将文件的每一行转换为 Erlang 术语并将结果传递给下一步。

  2. 处理
    问题也没有提到解析/处理输入的具体逻辑。您似乎也关心数据类型,因此我们将相应地转换并显示结果。Erlang 作为一种函数式语言自然会处理列表,所以在大多数情况下我们需要在lists模块上使用函数

  3. 输出
    您没有特别提到要在哪里显示结果(输出文件、屏幕/erlang shell 等),所以假设您只想在标准输出/erlang shell 中显示它。

    示例文件内容test1.txt(请注意每行末尾的点)

[["name "," col"," dist"," a"," angv"," r "],["apollo11 ","white","0.1"," 0"," 77760"," 0.15"]].
["planets ","earth","venus "].
["a","b"].

如何运行:solarSystem:process_file("/Users/macbook/Documents/test1.txt").
示例结果:

(dev01@Macbooks-MacBook-Pro-3)3> solarSystem:process_file("/Users/macbook/Documents/test1.txt").
apollo11 = ["white",0.1,0,77760,0.15] 
planets = ["earth","venus"] 
a = ["b"] 
Done processing 3 line(s) 
ok

模块代码:


-module(solarSystem). 

-export([process_file/1]).
-export([process_line/2]).
-export([format_item/1]).

%%This is the main function, input is file full path
%%Howto call: solarSystem:process_file("file_full_path").
process_file(Filename) ->
    %%Use file:consult to convert the file content into erlang terms
    %%File content is a dot (".") separated line
    {StatusOpen, Result} = file:consult(Filename),
    case StatusOpen of
        ok ->
                %%Result is a list and therefore each element must be handled using lists function
                Ctr = lists:foldl(fun process_line/2, 0, Result),
                io:format("Done processing ~p line(s) ~n", [Ctr]);
         _ ->   %%This is for the case where file not available
                io:format("Error converting file ~p due to '~p' ~n", [Filename, Result])
    end.

process_line(Term, CtrIn) ->
    %%Assume there are few possibilities of element. There are so many ways to process the data as long as the input pattern is clear.
    %%We basically need to identify all possibilities and handle them accordingly.
    %%Of course there are smarter (dynamic) ways to handle them, but below may give you some ideas.
    case Term of
        %%1. This is to handle this pattern -> [["name "," col"," dist"," a"," angv"," r "],["apollo11 ","white"," 0.1"," 0"," 77760"," 0.15"]]
        [[_, _, _, _, _, _], [Name | OtherParams]] ->
                                                        %%At this point, Name = "apollo11", OtherParamsList = ["white"," 0.1"," 0"," 77760"," 0.15"]
                                                        OtherParamsFmt = lists:map(fun format_item/1, OtherParams),
                                                        %%Display the result to standard output
                                                        io:format("~s = ~p ~n", [string:trim(Name), OtherParamsFmt]);
        %%2. This is to handle this pattern -> ["planets ","earth","venus "]
                             [Name | OtherParams] ->
                                                        %%At this point, Name = "planets ", OtherParamsList = ["earth","venus "]
                                                        OtherParamsFmt = lists:map(fun format_item/1, OtherParams),
                                                        %%Display the result to standard output
                                                        io:format("~s = ~p ~n", [string:trim(Name), OtherParamsFmt]); 
        %%3. Other cases
                                                    _ ->
                                                        %%Display the warning to standard output
                                                        io:format("Unknown pattern ~p ~n", [Term])
    end,
    CtrIn + 1.
    
%%This is to format the string accordingly
format_item(Str) ->
    StrTrim = string:trim(Str), %%first, trim it
    format_as_needed(StrTrim).

format_as_needed(Str) ->
    Float = (catch erlang:list_to_float(Str)),
    case Float of
        {'EXIT', _} ->  %%It is not a float -> check if it is an integer
                        Int = (catch erlang:list_to_integer(Str)),
                        case Int of
                            {'EXIT', _} ->  %%It is not an integer -> return as is (string)
                                            Str;
                                    _  ->   %%It is an int
                                            Int
                        end;
                _  ->   %%It is a float
                        Float
    end.
    
于 2020-12-01T12:03:18.087 回答