4

我需要一个能够改变元素值的动态长度数据结构。元素的顺序并不重要。

  • 如果我使用数组,我可以修改我的元素,但是长度有问题。解决方案是创建一个大小正确的新数组,每次都将所有元素复制到新数组中。这不是一个好主意,因为元素的数量经常变化。

  • 使用泛型列表比较好,但是修改过程真的很复杂:首先我需要删除我要更改的元素——泛型列表似乎没有简单的“删除”/“删除”方法,所以我尝试了“过滤器”,然后将修改后的元素添加到头部。它可以工作,但是对于如此简单的事情来说有点太复杂了。

是否有允许我动态更改长度和修改元素的数据结构,例如可修改列表或动态大小的数组?

4

2 回答 2

7

使用ResizeArray它是 CLI 类型List(T)的缩写,它提供您需要的功能,例如Remove

来自 MSDN 库:

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 没有实现任何接口,则没有默认比较器,并且必须显式提供比较器或比较委托。

List(T) 不能保证被排序。在执行需要对 List(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]
于 2012-06-11T11:00:11.550 回答
5

我建议使用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

arr.[idx] <- e关于您的第二个问题,您仍然可以使用与 with 一样的语法Array

为避免复杂的操作,您可以在F# PowerPack的ResizeArray 模块ResizeArray中使用高阶函数。这些函数会创建新的 s,因此性能并不理想。ResizeArray

// Use high-order functions to update items
let changeOneToThree (a: ResizeArray<_>) =
   ResizeArray.map (fun x -> if x = 1 then 3 else x) a

但是,您始终可以从那里开始并通过改变 current 进行优化ResizeArray

于 2012-06-11T11:01:05.583 回答