我可以通过F#中的键插入地图吗?

时间:2014-06-03 19:09:24

标签: map f#

我用F#搞砸了一下,我不太确定我是否正确地这样做了。在C#中,可以使用IDictionary或类似的东西来完成。

type School() =
   member val Roster = Map.empty with get, set

   member this.add(grade: int, studentName: string) =
      match this.Roster.ContainsKey(grade) with
        | true -> // Can I do something like this.Roster.[grade].Insert([studentName])?
        | false -> this.Roster <- this.Roster.Add(grade, [studentName])

如果它包含指定的键,或者我在这种情况下只是使用了错误的集合,是否有一种方法可以插入到地图中?

1 个答案:

答案 0 :(得分:6)

F#Map类型是从键到值的映射,就像普通的.NET Dictionary一样,除了它是不可变的。

如果我正确理解您的目标,您就会尝试为每个年级保留一份学生名单。在这种情况下,类型是从整数到名称列表的映射,即Map<int, string list>

地图上的Add操作实际上是添加替换一个元素,所以我认为这是{\ n}你想要的操作{ {1}}案例。在false案例中,您需要获取当前列表,附加新学生,然后替换现有记录。一种方法是写一些类似的东西:

true

这不是线程安全的(因为同时调用type School() = member val Roster = Map.empty with get, set member this.Add(grade: int, studentName: string) = // Try to get the current list of students for a given 'grade' let studentsOpt = this.Roster.TryFind(grade) // If the result was 'None', then use empty list as the default let students = defaultArg studentsOpt [] // Create a new list with the new student at the front let newStudents = studentName::students // Create & save map with new/replaced mapping for 'grade' this.Roster <- this.Roster.Add(grade, newStudents) 可能无法正确更新映射)。但是,您可以随时访问Add,对其进行迭代(或共享对它的引用),因为它是一个不可变的结构。但是,如果您不关心这一点,那么使用标准school.Roster也会非常好 - 取决于您的实际用例。