2014-03-05 4 views
2

비슷한 요소를 다트 목록에서 제거하고 싶습니다. 다트 목록에서는 유사성이 일부 부울 함수에 의해 제공됩니다. 티카에서 예를 들어 나는 다음과 같은 것을 얻을 것이다 :다트 목록에서 유사한 요소를 제거하는 방법은 무엇입니까?

Union[{2, -2, 1, 3, 1}, SameTest -> (Abs[#1] == Abs[#2] &)] 

이 문장은 다음 목록을 얻을 수 - {-2, 1, 3}. 효과적으로 각 동등한 클래스에서 하나의 요소를 유지하고 싶습니다.

나는 함수 list.retainWhere (e) => bool test (e))가 있음을 알고 있습니다. 불행히도이 테스트는 한 번에 하나의 값에서만 작동 할 수 있습니다. 또 다른 옵션은 물론, 이런 식으로 할 수 있습니다 (내 머리에서 쓰는 것)

i=0; 
for(final E in list) { 
    i++;  
    for(j=i; j<list.skip(i).length; j++) { 
    if sameTest(e, E) then list.removeAt(i+j); 
    } 
} 

그러나이 비트는보기 흉합니다.

어떤 조언이 필요합니까?

업데이트 자세한 내용은 내 문제를 명확히하고 아래에 제시된 조언을 사용하여 문제를 해결하는 방법을 보여줍니다.

class Pair<T> { 
    final T left; 
    final T right; 
    Pair(this.left, this.right);  
    } 

는 이제 구조와 같은 쌍 또는 채 갖고 싶어, 나는 서로 충분히 가까운 지점을 보유하고 싶지 않아요. 실제로 더 복잡한 경우에 차이가 너무 알렉산더 Ardhuin와 그의 주석의 솔루션을 채택 이렇게하려면 다음 2 개 요소를 고려를 e1e2 당신은 보장하기 위해 hashCode을 정의 할 필요가 e1.hashCode == e2.hashCode 그래서 여기

e1 == e2 경우 이동 :

int N=1000; 

LinkedHashSet<Pair<double>> myset = 
    new LinkedHashSet<Pair<double>>(
     equals: (Pair<double> e1, Pair<double> e2) =>    
     (e1.left - e2.left)*(e1.left - e2.left) + (e1.right - e2.right)*(e1.right - e2.right) < 1/N, 
     hashCode: (Pair<double> e){ 
     int ex = (e.left*N).round(); 
     int ey = (e.right*N).round(); 
     return (ex+ey).hashCode; 
     } 
); 

List<Pair<double>> list = [new Pair<double>(0.1,0.2), new Pair<double>(0.1,0.2001)]; 
myset.addAll(list); 

결과는 {0.1,0.2}이됩니다. list의 두 번째 요소가 {0.1, 0.201}으로 변경되면 예상대로 두 요소가있는 집합이 생성됩니다.

희망이 유용했습니다.

답변

3

당신은 LinkedHashSet를 사용하고 사용하는해시 코드에 해당 정의 할 수 있습니다.

import 'dart:collection'; 

main() { 
    final result = new LinkedHashSet<int>(
     equals: (int e1, int e2) => e1.abs() == e2.abs(), 
     hashCode: (int e) => e.abs().hashCode); 
    result.addAll([2, -2, 1, 3, 1]); 
    print(result); // {2, 1, 3} 
} 
+0

잘 보이지만 여전히 문제가 있습니다. 해시 코드가 있습니다. 나는 클래스'클래스 쌍을 가지고 {final T left; }}} {hashCode = true (최종 T right);} 그러면 해시 세트를 선언하려고 시도합니다. 'new LinkedHashSet > (쌍 : e1, 쌍 e2) => (e1.left -e2.left)^2 + e2right)^2 <0.01, hashCode : (쌍 e) => e.hashCode); ' 즉 충분히 먼 쌍만 있어야합니다. 'list = [new Pair (0.1,0.2), new Pair (0.1,0.200001)] 두 개 사이의 거리는 0.01보다 작습니다. 그러나'myset.addAll (list)'에는 하나가 아닌 두 개의 엘리먼트가있다. 어떻게 해결합니까? –

+1

2 요소 _e1_과 _e2_를 고려하면 _hashCode_를 정의하여 'e1 == e2' 인 경우'e1.hashCode == e2.hashCode'를 보장해야합니다. 이것은 귀하의 코드에 해당하지 않습니다. 퍼포먼스에 신경 쓰지 않는다면 위에 언급 한 조건을 만족하는'hashCode : (e) => 0'을 항상 사용할 수 있습니다. –

관련 문제