【问题标题】:How to combine 2 lists and add new ones using LINQ?如何使用 LINQ 组合 2 个列表并添加新列表?
【发布时间】:2014-10-22 07:08:06
【问题描述】:

有两个列表。我想根据键(属性)ID 组合两个列表,并使用列表 2 中的值更新此记录。必须添加不在列表 1 中的所有列表项。

我搜索了互联网并找到了有关 LINQ 连接功能的信息,但我还想使用 LINQ 将新记录/项目添加到列表中。有谁知道怎么做(使用 1 个 LINQ 查询)?

到目前为止我的代码。

public class Item
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Value { get; set; }
}

[TestFixture]
public class CompareListTest
{
    private List<Item> firstList;

    [SetUp]
    public void SetUp()
    {
        firstList.Add(new Item()
        {
            Id = "1",
            Name = "Name1",
            Value = "NotUpdated1"
        });
    }

    [Test]
    public void ShouldCombineTwoListsAndAddNewOnesUsingIdAsPrimaryKey()
    {
        List<Item> secondList = new List<Item>();
        secondList.Add(new Item()
        {
            Id = "1",
            Name = "NameUpdated1",
            Value = "Updated1"
        });
        secondList.Add(new Item()
        {
            Id = "2",
            Name = "NewOne",
            Value = "New"
        });

        var combineList = new CombineList();
        List<Item> combinedList = combineList.Update(firstList, secondList);
        Assert.That(combinedList.Count, Is.EqualTo(2));
        Assert.That(combinedList.FirstOrDefault(x => x.Id == "1").Value, Is.EqualTo("Updated1"));
        Assert.That(combinedList.FirstOrDefault(x => x.Id == "2").Value, Is.EqualTo("New"));
    }
}

public class CombineList
{
    public List<Item> Update(List<Item> firstList, List<Item> secondList)
    {
        var result = from x in firstList
                     join y in secondList
                     on x.Id equals y.Id
                     select new Item()
                     {
                         Id = y.Id,
                         Name = y.Name,
                         Value = y.Value
                     };
        return result.ToList();
    }
}

【问题讨论】:

  • 列表一中但不在列表二中的条目怎么办?同一个 ID 多次出现怎么办?顺序重要吗?
  • 不,顺序无关紧要。 id 是唯一的。测试应给出以下结果(共 2 项):{Id = 1, Name="NameUpdated1", Value = "Updated1"} 和项目 {Id = 2, Name="NewOne", Value = "New"}
  • 列表一中的条目而不是列表二中的条目也必须添加到结果中。
  • 看起来你需要一个完整的外部联接

标签: c# linq linq-to-objects


【解决方案1】:

如果我理解正确,您需要两个列表中的所有项目,但如果有 2 个具有相同 id 的项目,则需要第二个列表中的项目。

我能想到的是:取两个列表的交集(使用 first 列表中的值),然后取第一个列表中的项目减去交集的项目,然后取与第二个列表的联合。

var result = (secondList.Union(
    firstList.Except(
        from l in firstList
        join r in secondList
        on l.Id equals r.Id
        select l
    )
)).ToList();

【讨论】:

    【解决方案2】:

    Dennis_E 的替代方法是:

    1. 查找第一个列表中所有不在第二个列表中的项目
    2. 将第二个列表与第 1 步的结果结合起来

      var combinedList = secondList.Concat( firstList.Where(i1 => !secondList.Any(i2 => i2.Id == i1.Id)));

    我选择了Concat 而不是Union,因为顺序无关紧要,而且Item 类没有实现Equals

    为了性能,我选择了可​​读性稍差的!Any 而不是All。一旦找到一个匹配的项目,就不需要再进行比较了。

    我不知道两者在性能方面如何比较。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多