添加到列表第二类型列表中的第一个类型缺少对象

时间:2015-04-26 14:44:29

标签: c#

我有两个不同类型的列表。第一个列表是以下类的类型:

public partial class PersonOneProductOne
{
    public int PersonOneId { get; set; }
    public int ProductOneId { get; set; }
}

第二个列表是以下类的类型:

public partial class PersonTwoProductTwo
{
    public int PersonTwoId { get; set; }
    public int ProductTwoId { get; set; }
}

我想从PersonTwoProduct的列表类型中添加PersonOneProductOne缺少对象的列表类型,但不幸的是它不是那么容易,因为我还列出了如何将PersonOneId和ProductOneId从PersonOneProductOne类映射到PersonTwoProductTwo类中的PersonTwoId和ProductTwoId :

public class PersonOnePersonTwo
{
    public int PersonOneId { get; set; } 
    public int PersonTwoId { get; set; }
}

public class ProductOneProductTwo
{
    public int ProductOneId { get; set; }
    public int ProductTwoId { get; set; }
}

我写了下面的代码,但它很慢,是更好的方法吗?

// data:
List<PersonOneProductOne> personOneProductOneList = new List<PersonOneProductOne>();
List<PersonTwoProductTwo> personTwoProductTwoList = new List<PersonTwoProductTwo>();

// how to map:
List<PersonOnePersonTwo> personOnePersonTwoMapping = new List<PersonOnePersonTwo>();
List<ProductOneProductTwo> productOneProductTwoMapping = new List<ProductOneProductTwo>();

// my algorithm which is slow:
foreach (PersonTwoProductTwo personTwoProductTwo in personTwoProductTwoList)
{
    PersonOnePersonTwo personOnePersonTwo = personOnePersonTwoMapping.FirstOrDefault(x => x.PersonTwoId == personTwoProductTwo.PersonTwoId);
    ProductOneProductTwo productOneProductTwo = productOneProductTwoMapping.FirstOrDefault(x => x.ProductTwoId == personTwoProductTwo.ProductTwoId);

    if (personOnePersonTwo != null && productOneProductTwo != null)
    {
        PersonOneProductOne personOneProductOne = personOneProductOneList.FirstOrDefault(x => x.PersonOneId == personOnePersonTwo.PersonOneId && x.ProductOneId == productOneProductTwo.ProductOneId);

        if (personOneProductOne == null)
        {
            personOneProductOneList.Add(new PersonOneProductOne
                {
                    PersonOneId = personOnePersonTwo.PersonOneId,
                    ProductOneId = productOneProductTwo.ProductOneId
                });
        }
    }
}

1 个答案:

答案 0 :(得分:1)

下面的代码片段不会加快您的查询速度。它将您当前的逻辑转换为单个LINQ查询。我把它包括在内,因为它使你当前的逻辑更容易理解(即它更易读),这在尝试优化时总是一个很好的起点。

var result = 
    from person2product2 in personTwoProductTwoList
    from person1person2 in personOnePersonTwoMapping
    from product1product2 in productOneProductTwoMapping
    where person2product2.PersonTwoId == person1person2.PersonTwoId &&
          person2product2.ProductTwoId == product1product2.ProductTwoId &&
          !personOneProductOneList.Any(x =>
              x.PersonOneId == person1person2.PersonOneId &&
              x.ProductOneId == product1product2.ProductOneId)
    select new PersonOneProductOne {
        PersonOneId = person1person2.PersonOneId,
        ProductOneId = product1product2.ProductOneId
    };

personOneProductOneList.AddRange(result);

可以优化的一个显而易见的事情是使用具有O(1)查找时间的使用字典而不是您的&#34;映射&#34;列表,将有O(N)查找时间。

当使用字典并假设每个人的ID和产品ID都有一个条目时,可以将其转换为:

// Maps PersonTwoId (key) to PersonOneId (value)
Dictionary<int, int> personTwoPersonOneMapping;

// Maps ProductTwoId (key) to ProductOneId (value)
Dictionary<int, int> productTwoProductOneMapping;

var result = 
    from person2product2 in personTwoProductTwoList
    where !personOneProductOneList.Any(x =>
        x.PersonOneId == personTwoPersonOneMapping[person2product2.PersonTwoId] &&
        x.ProductOneId == productTwoProductOneMapping[person2product2.ProductTwoId])
    select new PersonOneProductOne {
        PersonOneId = personTwoPersonOneMapping[person2product2.PersonTwoId],
        ProductOneId = productTwoProductOneMapping[person2product2.ProductTwoId]
    };