2012-06-11 4 views
4

요소 값을 변경할 수있는 동적 길이 데이터 구조가 필요합니다. 요소의 순서는 중요하지 않습니다.목록, 배열 또는 다른 무엇?

  • 배열을 사용하면 요소를 수정할 수는 있지만 길이에 문제가 있습니다. 해결 방법은 올바른 크기의 새로운 배열을 만들고 매번 모든 요소를 ​​새로운 요소로 복사하는 것입니다. 요소의 수가 자주 변경되기 때문에 좋은 생각은 아닙니다.

  • 일반 목록을 사용하는 것이 더 좋지만 수정 프로세스는 정말 복잡합니다. 우선 변경하고 싶은 요소를 제거해야합니다. 일반 목록에는 간단한 "제거"/ "Delete"메서드를 사용하여 "Filter"를 시도한 다음 수정 된 요소를 머리에 추가했습니다. 그것은 작동하지만 너무 쉽게 뭔가 너무 복잡합니다.

나 동적으로 수정 가능한리스트 또는 동적 크기의 배열로 길이를 변경하여 소자를 수정 할 수 있도록하는 데이터 구조가 있는가?

+0

요소 순서가 중요하지 않은 경우 머리의 중요성은 무엇입니까? 객체에 수정 된 속성 datetime을 추가하고 객체가 변경되면이 변경 사항을 확인하면 sorteddictionary가 작동해야합니다. –

+2

다른 사람들이 말했듯이, 'ResizeArray'는 당신의 요구 사항과 일치 합니다만, 그것은 보통 너무 긴급한 F # 코드의 표시입니다. 그러나, 당신은 그러한 데이터 구조를 필요로한다고 말하지 않았으므로 실제 문제에 대한 대안적인 해결책이 더 기능적 일 수 있습니다. 그것에 대해 자세히 설명해 주시겠습니까? –

+1

@ 토마스 - 필자는 F #에서 명령형 코드를 사용하는 모든 사람들이 코칭을 받아야 함을 의미하지는 않는다. 기능적으로 항상 더 좋다. – Brian

답변

7

ResizeArray을 사용하십시오. CLI 유형 List(T)의 약어로, 예를 들어 Remove과 같이 필요한 기능을 제공합니다. MSDN 라이브러리에서

:

리스트 (T) 클래스는 ArrayList 클래스의 일반과 동일합니다. 은 크기가 인 배열을 사용하여 IList (T) 제네릭 인터페이스를 구현하므로 필요에 따라 동적으로 증가됩니다.

등의 메서드, IndexOf, LastIndexOf 및 을 제거하면 목록 요소에 동등 비교자를 사용합니다. 유형 T에 대한 기본 동일성 비교 자 은 다음과 같이 결정됩니다. 형식 T가 IEquatable (T) 제네릭 인터페이스를 구현하는 경우 동등 비교자는 해당 인터페이스의 같음 (T) 메서드입니다. 그렇지 않은 경우 기본 등호 은 Object.Equals (Object)입니다.

BinarySearch 및 Sort와 같은 메서드는 목록 요소에 대한 정렬 비교자를 사용합니다. 형식 T의 기본 비교자는 다음과 같이 결정됩니다. . 형식 T가 IComparable (T) 제네릭 인터페이스를 구현하는 경우 기본 비교자는 해당 인터페이스의 CompareTo (T) 메서드입니다. 그렇지 않으면 유형 T가 비 지속 IComparable 인터페이스를 구현하는 경우 기본 비교자는 해당 인터페이스의 CompareTo (Object) 메서드 입니다. 형식 T가 인터페이스를 구현하지 않으면 에는 기본 비교자가 없으며 비교 자 또는 비교 대리자는 명시 적으로 이어야합니다.

목록 (T)은 정렬되지 않을 수 있습니다. 목록 (T)을 정렬해야하는 작업 (예 : BinarySearch)을 수행하기 전에 목록 (T) 을 정렬해야합니다.

이 컬렉션의 요소는 정수 인덱스를 사용하여 액세스 할 수 있습니다. 이 컬렉션의 인덱스는 0부터 시작합니다.

List (T)는 참조 형식에 유효한 값으로 null 참조 (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] 
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 

, 당신은 여전히 ​​Array와 마찬가지로 구문 arr.[idx] <- e를 사용할 수 있습니다.

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을 변형하여 최적화 할 수 있습니다.