List,Array还是其他什么?

时间:2012-06-11 10:47:25

标签: .net arrays list data-structures f#

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

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

  • 最好使用通用列表,但修改过程非常复杂:首先我需要删除我想要更改的元素 - 通用列表似乎没有简单的“删除” /“删除”方法,所以我尝试了“过滤”一个 - 然后将修改后的元素添加到头部。它有效,但对于这么简单的东西来说有点太复杂了。

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

2 个答案:

答案 0 :(得分:7)

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

来自MSDN Library:

  

List(T)类是ArrayList类的通用等价物。它   使用大小为的数组实现IList(T)泛型接口   根据需要动态增加。

     

Contains,IndexOf,LastIndexOf和删除等方法使用   列表元素的相等比较器。默认的相等比较器   对于类型T,确定如下。如果类型T实现了   IEquatable(T)泛型接口,然后是相等比较器   该接口的Equals(T)方法;否则,默认相等   comparer是Object.Equals(Object)。

     

BinarySearch和Sort等方法使用了一个排序比较器   列表元素。类型T的默认比较器确定为   如下。如果类型T实现IComparable(T)通用接口,   那么默认比较器就是CompareTo(T)方法   接口;否则,如果类型T实现非通用IComparable   接口,然后默认比较器是CompareTo(Object)方法   那个界面。如果类型T既不实现接口,那么那里   不是默认比较器,并且必须是比较器或比较委托   明确提供。

     

无法保证列表(T)已排序。您必须对列表(T)进行排序   在执行需要的操作(例如BinarySearch)之前   列表(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]

答案 1 :(得分: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一样使用Array语法。

为避免对ResizeArray进行复杂操作,您可以使用ResizeArray module 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

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