비슷한 요소를 다트 목록에서 제거하고 싶습니다. 다트 목록에서는 유사성이 일부 부울 함수에 의해 제공됩니다. 티카에서 예를 들어 나는 다음과 같은 것을 얻을 것이다 :다트 목록에서 유사한 요소를 제거하는 방법은 무엇입니까?
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 개 요소를 고려를 e1
및 e2
당신은 보장하기 위해 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}
으로 변경되면 예상대로 두 요소가있는 집합이 생성됩니다.
희망이 유용했습니다.
잘 보이지만 여전히 문제가 있습니다. 해시 코드가 있습니다. 나는 클래스'클래스 쌍을 가지고 {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)'에는 하나가 아닌 두 개의 엘리먼트가있다. 어떻게 해결합니까? –
2 요소 _e1_과 _e2_를 고려하면 _hashCode_를 정의하여 'e1 == e2' 인 경우'e1.hashCode == e2.hashCode'를 보장해야합니다. 이것은 귀하의 코드에 해당하지 않습니다. 퍼포먼스에 신경 쓰지 않는다면 위에 언급 한 조건을 만족하는'hashCode : (e) => 0'을 항상 사용할 수 있습니다. –