如何有效地获取对象列表的唯一组合

时间:2017-02-11 00:08:25

标签: c# .net performance linq combinations

我有一个对象列表,我想从中创建独特的组合。

我拥有的对象是(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 City2 | 39402 | 1 | 59 | -5

City1 | 3840 | 42 | -12 | 5 City3 | 5934 | 99 | -55 | 3

City1 | 3840 | 42 | -12 | 5 City4 | 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 City4 | 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)
                    }
                }
            }

简而言之,方法是将两个列表一个完整,一个为空,将完整列表的每个元素与空列表进行比较,以查看它是否存在或转置是否存在以及是否不添加它。

它有效,但速度很慢,有没有更好的方法呢?

由于

2 个答案:

答案 0 :(得分: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]) ;

答案 1 :(得分: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