日期:2014-05-18  浏览次数:20876 次

不同类型的List找交集
C# code

情况1:
var pList1 = new List<Product>
{
    new Product {ID = 1, SubID = "AA", Price = 0.1 },
    new Product {ID = 2, SubID = "BB", Price = 0.2 },
    new Product {ID = 3, SubID = "BB", Price = 0.4 },
    new Product {ID = 4, SubID = "AA", Price = 0.7 },
    new Product {ID = 5, SubID = "CC", Price = 0.3 }
};

var pList2 = new List<SubProduct>
{
    new SubProduct { ID="AA" },
    new SubProduct { ID="BB" }
}

情况2:
var pList1 = new List<Product>
{
    new Product {ID = 1, SubID = "AA", Price = 0.1 },
    new Product {ID = 2, SubID = "BB", Price = 0.2 },
    new Product {ID = 3, SubID = "BB", Price = 0.4 },
    new Product {ID = 4, SubID = "AA", Price = 0.7 }
};

var pList2 = new List<SubProduct>
{
    new SubProduct { ID="AA" },
    new SubProduct { ID="BB" },
    new SubProduct { ID="CC" }
}



问题:
  1.情况1中pList1中有3个SubID,但是pList2中只有两个,所以pList1中的SubID="CC"为异常数据,需剔除.
  2.情况2中pList1中只有2个SubID,pList2中有三个,且pList2中的ID = "CC"的在pList1中的记录Count为零,需剔除.

现在用的最普通的内嵌循环, - -
C# code

IList<Product> tmpPList = new List<Product>();
foreach(SubProduct sp in pList2)
{
    var q = qList1.Where(s => s.SubID == sp.ID).Count() > 0
    if (q.Any())
    {
        tmpPList.Add(q);
    }       
}

//为什么要建立一个临时列表,因为后续要对这个列表进行重组,
//现在的更改决定了后面的列表更新内容
if(!tmpPList.Any())
{
    foreach(Product tp in tmpPList)
    {
        tmpList.Remove(tp);
        //do something
    }
}



请教有效率高点的写法,因为实际应用中这两个List的数据量比较大.

------解决方案--------------------
C# code
var pList1 = new List<Product>()
{
    new Product {ID = 1, SubID = "AA", Price = 0.1 },
    new Product {ID = 2, SubID = "BB", Price = 0.2 },
    new Product {ID = 3, SubID = "BB", Price = 0.4 },
    new Product {ID = 4, SubID = "AA", Price = 0.7 }
};

var pList2 = new List<SubProduct>()
{
    new SubProduct { ID="AA" },
    new SubProduct { ID="BB" },
    new SubProduct { ID="CC" }
};

var result = pList1.Where(x => pList2.Select(y => y.ID).Contains(x.SubID)).ToList();

------解决方案--------------------
var m_ilAllSelect = lstSource.Select(r => r.ID).AsEnumerable();//新选择的列表
///////下面开始处理了
List<int> m_ilNewSelect = m_ilAllSelect.ToList();//新选择列表
List<int> m_ilExcept = m_ilNewSelect.Except(m_mcuids).ToList(); //两者的不同之处
List<int> m_iExceptAfterAndNew = m_ilNewSelect.Except(m_ilExcept).ToList();//新选择列表与差集比较,则是新选择中的旧的
 http://www.cnblogs.com/greatverve/archive/2012/03/29/csharp-list-linq-Intersection.html
------解决方案--------------------
IList<ItemsTOP> listTOP = new ServiceTOP().GetItemsTOP();

IList<Items> list = new WCFServiceClient().GetItems();

var filteredListTOP = listTOP.Select(i => new { ID = i.id, Name = i.Name} ).Except( i => i.IdTOP );

------解决方案--------------------
来个快速的

C# code
var ids = pList2.Select(x => x.ID).Distinct().ToList();
var result = pList1.GroupBy(x => x.SubID).Where(x => ids.Contains(x.Key)).SelectMany(x => x).ToList();

------解决方案--------------------
如果你的电脑有多个处理器核,还可以更快(在一个四核处理器上大致能快3倍):

C# code
var ids = pList2.Select(x => x.ID).Distinct().ToList();
var result = pList1