我用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])
Run Code Online (Sandbox Code Playgroud)
有没有办法插入地图,如果它包含指定的键或在这种情况下我只是使用错误的集合?
F#Map
类型是从键到值的映射,就像普通的.NET一样Dictionary
,除了它是不可变的.
如果我正确理解你的目标,那么你就是要为每个年级保留一份学生名单.在这种情况下的类型是从整数到名称列表的映射,即Map<int, string list>
.
该Add
地图上的操作实际上无论是增加或替换的元素,所以我认为这是你在需要的操作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)
Run Code Online (Sandbox Code Playgroud)
这不是线程安全的(因为Add
并发调用可能无法正确更新映射).但是,您可以随时访问school.Roster
,安全地迭代它(或共享它的引用),因为它是一个不可变的结构.但是,如果您不关心这一点,那么使用标准Dictionary
也会非常好 - 取决于您的实际用例.