2017-02-11 36 views
1

我有一個對象的列表,我想從中進行唯一組合。如何高效地獲取對象列表的唯一組合

我有的對象是(CityObj);

public string City_Name; 
public int Population; 
double xcord; 
double ycord; 
double zcord; 

其結果將是,其中包含一個新的對象(CityComboObj)

public string City_NameA; 
public int PopulationA; 
double xcordA; 
double ycordA; 
double zcordA; 
public string City_NameB; 
public int PopulationB; 
double xcordB; 
double ycordB; 
double zcordB; 

數據集的樣本的列表如下;

  • City1 | 3840 | 42 | -12 | 5
  • City2 | 39402 | 1 | 59 | -5
  • City3 | 5934 | 99 | -55 | 3
  • City4 | 12394 | -56 | 9 | 16

對象的結果列表看起來像;

City1 | 3840 | 42 | -12 | 5城市2 | 39402 | 1 | 59 | -5

City1 | 3840 | 42 | -12 | 5城市3 | 5934 | 99 | -55 | 3

City1 | 3840 | 42 | -12 | 5城市4 | 12394 | -56 | 9 | 16

City2 | 39402 | 1 | 59 | -5 City3 | 5934 | 99 | -55 | 3

City2 | 39402 | 1 | 59 | -5 City4 | 12394 | -56 | 9 | 16

City3 | 5934 | 99 | -55 | 3城市4 | 12394 | -56 | 9 | 16

正如你所見,它只返回了唯一的結果。

目前我正在使用可怕的低效apporach去做這件事;

foreach (var element in CityListA) 
      { 
      if (!CityListB.Any(o => o.City_NameA == element.City_NameA && o.City_NameB == element.City_NameB)) 
       { 
        if (!CityListB.Any(o => o.City_NameA == element.City_NameB && o.City_NameB == element.City_NameA)) 
        { 
         CityListB.add(element) 
        } 
       } 
      } 

一言以蔽之的做法是採取兩個列表一個完整的和一個空的,比較空單的完整列表中的每個元素,看它是否存在,或轉存在,如果它不添加它。

它有效,但速度很慢,有沒有更好的方法來做到這一點?

謝謝

+0

你可以結合'Any'電話,換一個。 – Abion47

+0

如何以'if(!CityListB.Any(o =>(o.City_NameA == element.City_NameA && o.City_NameB == element.City_NameB)||(o.City_NameA == element.City_NameB && o.City_NameB) == element.City_NameA)))'所以你沒有循環兩次? –

+0

你的問題是「我有一系列長度爲n的獨特項目,我希望生成長度爲k <= n的所有子序列。我寫了一系列關於不同技術的文章。系列從這裏開始:https://ericlippert.com/2014/10/13/producing-combinations-part-one/但是,如果您對理論不感興趣並且只想要代碼,那麼它就在這裏:https:// gist.github.com/ericlippert/69c9e93b366f8cc5d6ac –

回答

1
Your code needs some reengineering, for example: 

internal class CityObjs : List<CityObj> 
{ 
} 

internal class CityObj 
{ 
    public string City_Name; 
    public int Population; 
    double xcord; 
    double ycord; 
    double zcord; 
} 

internal class CityComboObj 
{ 
    internal CityObj CityA ; 
    internal CityObj CityB ; 
    internal CityComboObj(CityObj A,CityObj B) { CityA=A ; CityB=B;} 
} 

internal class CityComboObjs: List<CityComboObj> 
{ 
} 

假設列表CityObjs初始化:

CityComboObjs = new CityComboObjs() ; 
for (int i=0;i<CityObjs.Count-1;i++) for (int j=i+1;j<CityObjs.Count;j++) 
    CityComboObjs.Add(new CityComboObj(CityObjs[i],CityObjs[j]) ; 
+0

謝謝,最終這做了我正在尋找,並在一小部分時間(和CPU)的成本。 –

0

這實際上工作。只需用真實物體替換簡單的整數。這個代碼的想法是,如你所問,更有效地做到這一點,而不檢查對是否已經存在。在你的情況myList[i]將返回一個CITY對象

using System; 
using System.Linq; 
using System.Collections.Generic; 

public class Program 
{ 
    public static void Main() 
    { 
     var myList = (new []{1 , 2, 3, 4}).ToList(); 
     var newList = new List<ListObject>(); 
     var count = myList.Count; 

     for (int i = 0; i < count - 1; i++) 
     {   
      for(int j = i + 1; j < count; j++) 
      { 
       newList.Add(new ListObject(){ I = myList[i], J = myList[j]}); 
      } 
     } 
     newList.ForEach(x => Console.WriteLine(x)); 
    } 

    class ListObject 
    { 
     public int I {get; set;} 
     public int J {get; set;} 

     public override string ToString() 
     { 
      return I + " - " + J; 
     } 
    } 
} 

輸出
1 - 2
1 - 3
1 - 4
2 - 3
2 - 4
3 - 4

相關問題