2014-03-05 37 views
2

我想從飛鏢列表中刪除類似的元素,其中相似性由布爾函數給出。 例如Mathematica中我會實現這一如下:如何從飛鏢列表中刪除相似的元素?

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); 
    } 
} 

但我覺得這有點醜。

有什麼建議嗎?

UPDATE 我會更詳細地闡明我的問題,然後使用下面的建議說明如何解決它。

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; (等於:(對 e1,對 e2)=>(e1.left-e2.left)^ 2 +(e1.right-t);}然後我嘗試聲明一個hashset 'new LinkedHashSet > e2.right)^ 2 <0.01,hashCode :(對 e)=> e.hashCode);' Ie只有足夠遠的對必須留下。讓'list = [new Pair (0.1,0.2),new Pair (0.1,0.200001)]'這兩者之間的距離小於0.01。但'myset.addAll(list)'包含兩個元素而不是一個。我如何解決它? –

+1

考慮到2個元素_e1_和_e2_,你必須定義_hashCode_以確保'e1.hashCode == e2.hashCode'如果'e1 == e2'。你的代碼不是這種情況。如果你真的不關心性能,你總是可以使用'hashCode:(e)=> 0'來滿足上面提到的條件。 –