【问题标题】:Iteration in two list在两个列表中迭代
【发布时间】:2018-04-23 15:59:13
【问题描述】:

我一周前问过这个问题,现在我发现了一些我错过的东西。我不知道如果我重新打开这个问题是否会得到任何答复,这就是我创建一个新问题的原因。最后一个条件不起作用。 我正在尝试在具有不同对象的两个列表中进行迭代。当我比较 listTest1 和 listTest2 时,如果它们满足以下条件,我会将记录添加到第三个列表中

  • 如果缩写和日期相同,我添加的对象来自 listTest2 到 listTest3
  • 如果缩写相同但日期不同,我将添加 对象从 listTest2 到 listTest3 我正在切换完成 属性为真。另外,我正在添加来自 listTest1 的记录 列出Test3。
  • 如果 listTest1 中的缩写在 listTest2 中不存在,我将添加 从 listTest1 到 listTest3 的记录。
  • 如果 listTest2 中的缩写不存在于 listTest2 中。我正在添加 从listTest2到listTest2的记录

我知道这听起来很令人困惑,这就是为什么我会告诉你我得到了什么以及我期待什么。

我知道了,缺少测试 6 对象

class Program
{
    static void Main(string[] args)
    {
        Test1 test1 = new Test1() { abbrv = "Test1", date = new DateTime(2017, 11, 12), completed = false };
        Test1 test2 = new Test1() { abbrv = "Test2", date = new DateTime(2017, 12, 17), completed = false };
        Test1 test5 = new Test1() { abbrv = "Test5", date = new DateTime(2017, 12, 12), completed = false };

        Test2 test3 = new Test2() { abbrv = "Test1", date = new DateTime(2017, 11, 12), completed = false, abbrevName = "AbbrvName1" };
        Test2 test4 = new Test2() { abbrv = "Test2", date = new DateTime(2017, 12, 12), completed = false, abbrevName = "AbbrvName2" };
        Test2 test7 = new Test2() { abbrv = "Test5", date = new DateTime(2017, 12, 18), completed = false, abbrevName = "AbbrvName3" };
        Test2 test6 = new Test2() { abbrv = "Test6", date = new DateTime(2017, 12, 18), completed = false, abbrevName = "AbbrvName3" };
        List<Test1> listTest1 = new List<Test1>();
        List<Test2> listTest2 = new List<Test2>();
        List<Test2> listTest3 = new List<Test2>();
        listTest1.Add(test1);
        listTest1.Add(test2);
        listTest1.Add(test5);
        listTest2.Add(test6);
        listTest2.Add(test3);
        listTest2.Add(test4);
        listTest2.Add(test7);
        for (int i = 0; i < listTest1.Count; i++)
        {
            bool abbrvFound = false;
            for (int a = 0; a < listTest2.Count; a++)
            {
                if (listTest1[i].abbrv != listTest2[a].abbrv)
                {
                    continue;
                }

                abbrvFound = true;
                if (listTest1[i].date == listTest2[a].date)
                {
                    listTest3.Add(listTest2[a]);
                }
                else
                {
                    listTest3.Add(new Test2() { abbrv = listTest2[a].abbrv, date = listTest2[a].date, completed = true, abbrevName = listTest2[a].abbrevName });
                    listTest3.Add(new Test2() { abbrv = listTest1[i].abbrv, date = listTest1[i].date, completed = listTest1[i].completed, abbrevName = string.Empty });
                }
            }
            if (!abbrvFound)
            {
                listTest3.Add(new Test2() { abbrv = listTest1[i].abbrv, date = listTest1[i].date, completed = listTest1[i].completed, abbrevName = string.Empty });
            }
        }
        foreach (var test in listTest3)
        {
            Console.WriteLine(test.abbrv + " " + test.date + " " + test.completed + " " + test.abbrevName);
        }
        Console.Write(1);
    }
}

public class Test1
{
    public string abbrv { get; set; }
    public DateTime date { get; set; }
    public bool completed { get; set; }
}
public class Test2
{
    public string abbrv { get; set; }
    public DateTime date { get; set; }
    public bool completed { get; set; }
    public string abbrevName { get; set; }
}

【问题讨论】:

  • 你的最后一个条件没有意义。
  • 您能否突出显示您认为正在做最后一点的代码?
  • 谢谢。为什么最后一个条件没有意义。没有执行最后一个条件的代码
  • 认为你的意思是“如果listTest1中不存在listTest2的缩写。我正在将listTest2中的记录添加到listTest3”。但是,您只提到 listTest2
  • 那么你做最后一点的问题到底是什么?这似乎是前一点的一个相当简单的变体(即,您已经弄清楚如何在列表 1 中找到不在列表 2 中的东西,为什么不能在列表 2 中找到不在列表中的东西?列表 1) 中的 t。所以你有这个问题吗?您是否写过一些由于某种原因无法正常工作的东西?事实上,你能不知道如何创建相同的东西,而是反过来吗?

标签: c#


【解决方案1】:

我不确定我是否完全遵守了您声明的条件,但您似乎加入了两个不同的列表。为此,您可能会发现以下 LINQ 全外连接很有帮助。

var leftJoin = from t1 in listTest1
    join t2 in listTest2 on t1.abbrv equals t2.abbrv into lj
    from s in lj.DefaultIfEmpty()
    select new Test2() {abbrv = t1.abbrv, date = t1.date, completed = t1.completed, abbrevName = s.abbrv};

var rightJoin = from t2 in listTest2
    join t1 in listTest1 on t2.abbrv equals t1.abbrv into rj
    from s in rj.DefaultIfEmpty()
    select t2;

var fullOuterJoin = leftJoin.Union(rightJoin);

【讨论】:

    【解决方案2】:

    我将使用LINQ 将检查存在的部分分开,以便查找存在于一个列表中而不存在于另一个列表中的对象。
    然后在其余条件下使用您的算法

    这里是一个示例,展示了如何通过缩写名称查找未被 2 个列表共享的对象:

    var result = listTest1.Where(l => !listTest2.Any(l2 => l2.abbrv == l.abbrv));
    var result2 = listTest2.Where(l => !listTest1.Any(l1 => l1.abbrv == l.abbrv));
    
    Console.WriteLine("objects that exist in list 1 and not list list 2, based on abbrv string");
    foreach (var t in result)
    {
        Console.WriteLine(t.abbrv);
    }
    Console.WriteLine("objects that exist in list 2 and not list list 1, based on abbrv string");
    foreach (var t in result2)
    {
        Console.WriteLine(t.abbrv);
    }
    

    执行此操作的输出将是:

    objects that exist in list 1 and not list list 2, based on abbrv string
    objects that exist in list 2 and not list list 1, based on abbrv string
    Test6
    

    【讨论】:

      【解决方案3】:

      我建议使用MoreLINQ's FullJoin method

      public static List<Data> GetResults(List<Data> list1, List<Data> list2)
      {
          var joined = list1.FullJoin(list2, key1 => key1.Abbrv,
              firstSelector => new Data
              {
                  Abbrv = firstSelector.Abbrv,
                  Date = firstSelector.Date,
                  Desc = firstSelector.Desc
              },
              secondSelector => new Data
              {
                  Abbrv = secondSelector.Abbrv,
                  Date = secondSelector.Date,
                  Desc = secondSelector.Desc
              },
              (first, second) => new Data
              {
                  Abbrv = second.Abbrv,
                  Date = second.Date,
                  Desc = second.Desc
              });
      
          var mem = joined.ToList();
      
          return mem;
      }
      

      单元测试

      [TestMethod]
      public void FullTest()
      {
          //arrange
          var listTest1 = GetTest1Data();
          var listTest2 = GetTest2Data();
      
          //act
          var res = Class1.GetResults(listTest1, listTest2);
      
          //assert
          //If the abbrv and the date is the same I am adding the object from listTest2 to listTest3
          //If the abbrv is the same but the date is different I am adding the object from listTest2 to listTest3 and I am switching the completed property to true.In addition, I am adding the record from listTest1 to listTest3.
          //If the abbrv from listTest1 doesn't exist in listTest2 I am adding the record from listTest1 to listTest3.
          //If the abbrv from listTest2 doesnt exist in listTest2.I am adding the record from listTest2 to listTest2
          var expected = new List<Data> { new Data { Abbrv = "InBothSameDate", Date = new DateTime(2017, 11, 12), Desc = "From2" },
              new Data{ Abbrv="InBothDifferentDate", Date = new DateTime(2017, 12, 12), Desc = "From2" },
              new Data{ Abbrv="OnlyIn1", Date = new DateTime(2017, 1, 1), Desc = "From1"  },
              new Data{ Abbrv="OnlyIn2", Date = new DateTime(2017, 1, 31), Desc = "From2"  }
          };
      
          //https://stackoverflow.com/questions/11055632/how-to-compare-lists-in-unit-testing
          CollectionAssert.AreEqual(res, expected);
      }
      

      Full Source Code

      【讨论】:

        猜你喜欢
        • 2019-11-28
        • 2014-02-15
        • 2022-06-27
        • 1970-01-01
        • 1970-01-01
        • 2016-04-07
        • 2010-10-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多