2017-02-22 1 views
3

루프 내에서 다음 반복에서 필요한 목록에 새 요소를 추가합니다. List<T>.F # : mutable .Net List를 사용하여 동일한 목록에 요소를 추가 할 수 있습니까?

F# 일반적으로 불변의 컬렉션을 사용하는 것이 좋습니다. 그리고 그것은 내가 쓸모없는 list 또는 seq을 사용하여 원하는 것을 달성 할 수없는 것으로 보입니다.

가변적 인 .Net List<T>을 계속 사용하는 것이 허용됩니까? 아니면 불변의 것을 사용하는 것이 좋습니다? 그렇다면 어떻게 할 수 있습니까?

내 코드는 약간 길고 복잡하다, 그래서이 의사 F # 코드를 살펴 보자 :

let children = new List<node>() 
let bestBranchEntropies = entropiesSuchAs data.Rows parents 
//Finding the best children for the best parent 
bestBranchEntropies |> Seq.iter (fun bestBranch -> let attribut = IGetTheAttributByMaximumGainHere 
                //Creating one of the children in every iteration 
                let node = { 
                   content = attribut; 
                   branch = Some(fst bestBranch); 
                   children = None; 
                   isLeaf = false; 
                   } 
                //Considering it a child 
                children.Add node 

           ) 
         //After having all the children 
         let children' = children |> Seq.map (fun child -> { 
                      content = child.content; 
                      branch = child.branch; 
                      children = //recursive call here to do the same work above (getting children again, yeah it's a tree) 
                      isLeaf = child.isLeaf; 
                      }) 

         Some(children') 
+2

"허용 가능"은 매우 주관적입니다. 그런 말을하는 것 : Acceptable? 가능성이 가장 높습니다. 필요한? 가능성이 높습니다. 더 빠르게 변경할 수 있습니까? 불분명 함. 문맥을 더 제공하면 더 나은 답변을 얻을 수 있습니다. 어떻게 그 목록을 만들고 있습니까? 너는 어떻게 사용하고 있니? –

+0

F #에는 변경 가능한 목록 유형에 대한 특수 유형 약어가 있으므로 사용하는 것이 좋습니다. –

+0

불변의 대안을 사용할 수있는 가능성은 거의 확실합니다. 문맥을 제공하면 아마 어떻게 설명 할 수 있습니다. – TheInnerLight

답변

4

최대한 멀리 볼 수있는, 변경 가능한 목록 필요 (확실히 없다 당신의 의사 코드 경우 문제를 완전히 반영합니다.)

let children = 
    bestBranchEntropies 
    |> Seq.map (fun bestBranch -> 
     let attribut = IGetTheAttributByMaximumGainHere 
     //Creating one of the children in every iteration 
     { 
      content = attribut; 
      branch = Some(fst bestBranch); 
      children = None; 
      isLeaf = false; 
     } 
    |> Seq.toList 
children 
|> Seq.map (fun child -> 
    { 
     content = child.content 
     branch = child.branch 
     children = //recursive call here to do the same work above (getting children again, yeah it's a tree) 
     isLeaf = child.isLeaf 
    } 
) 
|> Some 

첫 번째 Seq.toList는 생략 할 수있다, 당신은을 통해 파이프 모든 방법을 사용할 수 있습니다 다음과 같은 고려하십시오. 의사 코드에서 전체 두 번째 루프가 실제로 첫 번째 루프와 안전하게 병합 될 수있는 것처럼 보입니까?

+0

두 번째 루프에서 재귀 호출에 대한 주석 처리 된 비트가 까다로운 비트라고 가정합니다. – scrwtp

+0

물론 가능합니다. 그러나 여기에있는 것만으로 작업 할 수 있습니다 :-) –

3

의사 코드에서는 명확하지 않지만 "실제 트리 구조를 탐색 할 때 누적 기 대신에 변경 가능한 목록을 사용할 수 있습니까?"라는 질문을하는 것이 좋습니다. ,

  1. 변경이 용이 한 객체가 함수에 로컬 달리 접근 및 변조 될 수없는,
  2. 그것은 목적이 명확하게 의견이 표시되어있다 :

    나는 그것이 잘 말하고 싶지만, 그건 제공 그래서 미래의 메인테이너들은 코드를 리팩토링 할 때 (그리고 변경 가능한 객체가 불변이라고 잘못 가정 할 때) 그것에 넘어 가지 않을 것입니다.

그것은 확실히 쓰기에 갈 필요가 많은 시간을 절약 적절한 꼬리 재귀 (물론 옵션 물론입니다, this blog post series 참조) 트리 fold. 그리고 만약 여러분이 끝까지 글을 쓰더라도, 먼저 프로토 타입을 프로토 타이핑하는 것이 공정한 선택입니다.

이 목적을 위해 변경 가능한 모음이 아닌 ref cells + 불변의 모음을 선호합니다. ref 셀을 변경하기 위해 필요한 추가 구문을 사용하면 변경 가능한 목록에서 Add을 호출하는 것과는 대조적으로 무엇이 진행되고 있는지 명확하게 알 수 있습니다.

+2

그리고 여기에 불변 목록이 실제로 놀랄만큼 성과가 있으며 꽤 많은 경우에 변경 가능한 목록을 이깁니다. –

관련 문제