Fra*_*oty 4 .net arrays f# list data-structures
我需要一个动态长度的数据结构,能够更改元素值.元素的顺序并不重要.
如果我使用数组我可以修改我的元素,但我的长度有问题.解决方案是创建一个正确大小的新数组,并每次将所有元素复制到新数组中.不是一个好主意,因为元素的数量经常变化.
最好使用通用列表,但修改过程非常复杂:首先我需要删除我想要更改的元素 - 通用列表似乎没有简单的"删除"/"删除"方法,所以我尝试了"过滤器" - 然后将修改后的元素添加到头部.它有效,但对于这么简单的事情来说有点太复杂了.
是否有一个数据结构允许我动态更改长度并修改元素,如可修改列表或动态大小的数组?
使用ResizeArray.它是CLI类型List(T)的缩写,它提供了您需要的功能,例如Remove.
来自MSDN Library:
List(T)类是ArrayList类的通用等价物.它使用一个数组实现IList(T)泛型接口,该数组的大小根据需要动态增加.
Contains,IndexOf,LastIndexOf和Remove等方法对列表元素使用相等比较器.类型T的默认相等比较器确定如下.如果类型T实现IEquatable(T)泛型接口,那么相等比较器是该接口的Equals(T)方法; 否则,默认的相等比较器是Object.Equals(Object).
BinarySearch和Sort等方法使用列表元素的排序比较器.类型T的默认比较器确定如下.如果类型T实现IComparable(T)泛型接口,则默认比较器是该接口的CompareTo(T)方法; 否则,如果类型T实现非通用IComparable接口,则默认比较器是该接口的CompareTo(Object)方法.如果类型T既不实现接口,也没有默认比较器,并且必须显式提供比较器或比较委托.
列表(T)不保证排序.在执行需要对列表(T)进行排序的操作(例如BinarySearch)之前,必须对List(T)进行排序.
可以使用整数索引访问此集合中的元素.此集合中的索引从零开始.
List(T)接受空引用(在Visual Basic中为Nothing)作为引用类型的有效值,并允许重复元素.
一个例子F#:
open System
// an integer list
let intList =
let temp = new ResizeArray<int>() in
temp.AddRange([| 1; 2; 3 |]);
temp
// print each int using the ForEach member method
intList.ForEach( fun i -> Console.WriteLine(i) )
// unpack items from the resize array
let itemOne = intList.Item(0)
let itemTwo = intList.[1]
Run Code Online (Sandbox Code Playgroud)
我建议使用ResizeArray.它基本上是System.Collections.Generic.List <'T>,如果元素数量经常变化,它是完美的.
// Add items to a ResizeArray based on a condition
let filterRange predicate (i, j) =
let results = ResizeArray(j-i+1) // reserve enough memory
for k = i to j do
if predicate k then results.Add(k)
results
Run Code Online (Sandbox Code Playgroud)
关于你的第二个问题,你仍然可以使用的语法arr.[idx] <- e与Array.
为了避免复杂的操作ResizeArray,你可以在使用高阶函数ResizeArray模块从F#PowerPack中.这些功能创造了新ResizeArray的功能,因此性能并不理想.
// Use high-order functions to update items
let changeOneToThree (a: ResizeArray<_>) =
ResizeArray.map (fun x -> if x = 1 then 3 else x) a
Run Code Online (Sandbox Code Playgroud)
但是,您始终可以从那里开始并通过改变电流进行优化ResizeArray.