2013-03-12 2 views
2

ОПИСАНИЯ ПРОБЛЕМЫ:C# Фильтр список двойных [] значения

У меня есть список двойных значений [] представляющих векторы, где 0-й элемент вектора соответствует физической длине вектора, а другим три (1-3) соответствуют компонентам x, y и z. Список содержит около 1000000 записей. Так что перфермонс будет проблемой. Я заказал список по длине векторов. Теперь мне нужно отфильтровать список таким образом, чтобы сохранялись векторы разной длины. И если длина одного и того же фильтра, те, которые содержат разные записи (не пермутации) в позиции 1-3, остаются такими, как указано в примере. Пожалуйста, дайте мне знать, если вам нужна дополнительная информация. В процессе фильтрации векторы не должны изменяться.

ВОПРОС: Как это можно реализовать с использованием C# и, если возможно, linq?

Пример:

0, 0,  0;  0,0000 -> select 
0, 1, -1;  8,2883 -> select 
1, 0, -1;  8,2883 -> not select 
0, -1,  1;  8,2883 -> not select 
-1, 0,  1;  8,2883 -> not select 
1, -1,  0;  8,2883 -> not select 
-1, 1,  0;  8,2883 -> not select 
1, 1, -2;  14,3558 -> select 
... 
2,  2, -5; 38,6145 -> select 
-2, -2,  5; 38,6145 -> not select 
1,  4, -4; 38,6145 -> select 
4,  1, -4; 38,6145 -> not select 
-1, -4,  4; 38,6145 -> not select 
-4, -1,  4; 38,6145 -> not select 
-1,  4, -4; 38,6145 -> not select 
4, -1, -4; 38,6145 -> not select 
-4,  1,  4; 38,6145 -> not select 
1, -4,  4; 38,6145 -> not select 
-2,  5, -2; 38,6145 -> not select 
5, -2, -2; 38,6145 -> not select 
2, -5,  2; 38,6145 -> not select 
-5,  2,  2; 38,6145 -> not select 
4, -4, -1; 38,6145 -> not select 
-4,  4, -1; 38,6145 -> not select 
-4,  4,  1; 38,6145 -> not select 
4, -4,  1; 38,6145 -> not select 
... 

КОД:

private static double absm = 0; 
private static int[] m = new int[3]; 
private static int[] m2 = new int[3]; 
private static List<double[]> ihkl1 = new List<double[]>(); 
private static List<double[]> ihkl2 = new List<double[]>(); 

... 

private static void init_latt() 
{ 
    for (int i = -kmax[2]; i < kmax[2]; i++) 
    { 
     m[2] = i; 
     for (int j = -kmax[1]; j < kmax[1]; j++) 
     { 
      m[1] = j; 
      for (int k = -kmax[0]; k < kmax[0]; k++) 
      {       
       m[0] = k; 
       absm = calcabsm(metten, m);            
       if (absm < gmax) 
       { 
        double[] row1 = new double[4]; 
        row1[0] = absm; 
        row1[1] = (double)m[0]; 
        row1[2] = (double)m[1]; 
        row1[3] = (double)m[2]; 
        ihkl1.Add(row1); 
       } 
      } 
     } 
    }  
    ihkl2 = ihkl1.AsParallel().OrderBy(x => x[0]).ToList(); 
} 
... 
+9

Первое предложение: перейти от «Список ' к «списку », где «Вектор» является подходящей инкапсуляцией четырех значений. Ваш код будет * намного более понятным. –

+1

[Что вы пробовали до сих пор] (http://whathaveyoutried.com)? Где вы застряли? Пожалуйста, разместите свой текущий код и объясните, где он упадет. – Oded

+0

list.distinct(); – 1Mayur

ответ

0

Прежде всего, я согласен с Jon Skeet's предложение использовать класс Vector, который инкапсулирует эти double массивы. После этого вы можете сделать:

public class VectorEqualityComparer : IEqualityComparer<Vector> 
{ 
    public bool Equals(Vector x, Vector y) 
    { 
     //here you implement the equality among vectors you defined in your question 
    } 

    public int GetHashCode(Vector obj) 
    { 
     //you can return something like obj.InnerArray.GetHashCode() 
    } 
} 

Теперь, если у вас есть список Vector, а именно yourList, вы можете позвонить:

var result = yourList.Distinct(new VectorEqualityComparer()); 

Надеются, что это поможет вам достичь того, чего вы хотите. Удачи!!!

+0

Большое спасибо, я постараюсь ... если у вас будут дополнительные вопросы, я отправлю их здесь – user2143695