在访问F#列表中的数据时感到困惑

时间:2015-02-14 06:19:21

标签: f# tuples

//Return a tuple from a text file:
let ExtractFromLine (line:string) =
 let strings = line.Split('\t') //data members are spaced by tab
 let strlist = Array.toList(strings) //each data member is now a list of str
 let year = System.Int32.Parse(strlist.Head) //year is first in file, so Head
 let values = List.map System.Double.Parse strlist.Tail //tail are all values
 let average = List.average values //not part of text file
 let min = List.min values //not part of text file
 let max = List.max values //not part of text file
 (year, values, average, min, max) //return tuple with all info

//----------
let rec createList fileline =
 if fileline = [] then
  []
 else 
  let (year, values, average, min, max) = ExtractFromLine fileline.Head
  let l = (year, values, average, min, max) :: createList fileline.Tail
  l

//------------
let main argv =
 let file = ReadFile "data.txt"

 let biglist = createList file //recursive function to make a list of tuples
 printfn"%A" biglist //This prints the year, all values, average, min, and max for each tuple created

我现在有一个巨大的元组列表,其中包含我需要的所有信息。 我是否保留了访问内部所有元素并对其进行计算的可能性?我使用C ++编程,并且该解决方案可以使用该语言,但在我看来,F#更强大。我确信它可能,我只是错过了基础知识。

例如,如何打印所有年份的所有值的平均值? 我想到了for循环,但我不确定如何迭代。

for(all tuples in biglist)
printfn"%A:%A" tuple.year tuple.average
显然这是错的,但我想你们都明白我要做的事情。

上述问题涉及在列表中一次从一个元组中提取数据。 如果我想打印最大的平均值怎么办?这将涉及访问每个元组的平均数据成员并比较它们以返回最大的平均数据。我是否必须创建包含这些平均值的另一个列表?

我了解了fst和snd,但我很难将它应用到这个例子中。 如果问题太多,你不必回答所有问题,但是当我开始使用这种语言时,我们非常感谢任何帮助,谢谢

2 个答案:

答案 0 :(得分:3)

你可以循环使用F#,但它是来自命令式编程世界的构造。更惯用的方法是以递归方式访问列表中的项目。

下面是一些创建元组的示例代码,构造一个列表,然后访问项目并检查哪个更大。查看代码,平均值是元组中的第三项。这就是为什么我添加了trd功能的原因。它需要一个5项元组并返回第三项。

prcsLst函数有两个参数:一个列表和一个起始最大值。我们的想法是,在处理列表时,我们采用头部(列表中的第一项),将其平均值与当前最大值进行比较。无论哪个更大都与列表的尾部(没有第一个项目的列表)一起传递到下一个递归轮次。在这种情况下,作为初始最大值我传递了第一个项目的平均值。

您可以在F#Interactive中运行该示例以查看结果。

// create sample tuples
let t1 = (2014, 35, 18, 5, 45)
let t2 = (2014, 32, 28, 8, 75)
let t3 = (2014, 25, 11, 9, 55)
let t4 = (2015, 16, 13, 2, 15)
let t5 = (2015, 29, 15, 1, 35)

// create sample list
let lst = [t1;t2;t3;t4;t5]

// a function to return third item in a tuple
let trd (_,_,t,_,_) = t

// process list recursively
let rec prcsLst l max =
    match l with
    | [] -> max
    | hd::tl ->
        if (trd hd) > max then
            prcsLst tl (trd hd)
        else
            prcsLst tl max


// invoke the method on the sample list
// as a starting point use the first item in the list
prcsLst lst (trd t1);;

答案 1 :(得分:1)

在手机上请原谅我没有做任何代码示例:)

我怀疑你的拼图中缺少的部分称为模式匹配。在F#中,你可以像这样解决元组的元素:

let (y, v, Av, mn, mx) = mytuple

请注意,您也可以在函数声明中以及执行“匹配”时使用它。

('twoples'有例外,你可以使用'fst'和'snd'这两个函数。

你应该玩的另一件事是|>操作