【问题标题】:managing items in a List based off some conditions in C#根据 C# 中的某些条件管理列表中的项目
【发布时间】:2023-03-14 21:08:01
【问题描述】:

我有几个列表 List<OldData> oldItems = new List<OldData>();List<NewData> newItems = new List<NewData>();

我在这里试图实现的是避免一些冗余数据进入的可能性,因此在将值添加到列表之前检查一些条件。

首先在 oldItems 我将存储一些值,在 newItems 列表中我将存储一组完全不同的值,但情况总是如此newItems 列表中可能有一些值已存在于 oldItems 列表中。

正在使用的两个变量是一个Name变量和一个存储某个路径的path变量

所以首先我想检查旧项目列表中的名称是否与新项目列表中的名称相同的任何值, 如果有一个项目我要检查相应项目的相应Path变量是否相同,

如果相同,我可以简单地保持该项目在 OldItems 列表中的方式,如果恰好不同,我将从旧项目列表中删除它(然后在新项目列表中使用该项目)

以上所有内容都在一个坚果壳中,

我想在旧项目列表中检查新项目列表中是否有与之对应的名称 如果有,我想检查两个List中同名的两个项目的Path变量中的对应值是相同还是不同

我已经制作了一个简单的虚拟应用程序来演示这个,但我真的坚持我如何实现逻辑

有什么建议吗?

class Program
{
    static void Main(string[] args)
    {

        List<OldData> oldItems = new List<OldData>();

        OldData oldData1 = new OldData();
        oldData1.Name = "Test01";
        oldData1.OriginalPath = "D:/Temp01";

        oldItems.Add(oldData1);


        OldData oldData2 = new OldData();
        oldData1.Name = "Test02";
        oldData1.OriginalPath = "D:/Temp02";
        oldItems.Add(oldData2);


        List<NewData> newItems = new List<NewData>();

        NewData newData1 = new NewData();
        newData1.Name = "Test01";
        newData1.OriginalPath = "D:/Temp01";

        newItems.Add(newData1);

        NewData newData2 = new NewData();
        oldData1.Name = "Test05";
        oldData1.OriginalPath = "D:/Temp05";
        newItems.Add(newData2);

        foreach (var item in oldItems)
        {
            //Check if there are any Names which are same from the new Item list
            //If if there is such an item check if the OriginalPath variable is the same iin both
            //If yes => Remove that particular item from the Old data List 
            //If Not => Keep that Item in  the old data List
        }
    }
}

class OldData
{
    public string Name { get; set; }
    public string OriginalPath { get; set; }
}

class NewData
{
    public string Name { get; set; }
    public string OriginalPath { get; set; }
}

在这种情况下,由于值Test01是两个List共有的,它会检查两个项目对应的路径变量值是否相同

【问题讨论】:

标签: c# .net list linq


【解决方案1】:

您的虚拟应用程序正在使用相同的对象 (oldData1)。

请使用简单的 LINQ 参考以下代码。

class Program
{
    static void Main(string[] args)
    {
        List<OldData> oldItems = new List<OldData>();

        OldData oldData1 = new OldData();
        oldData1.Name = "Test01";
        oldData1.OriginalPath = "D:/Temp01";

        oldItems.Add(oldData1);


        OldData oldData2 = new OldData();
        oldData2.Name = "Test02";
        oldData2.OriginalPath = "D:/Temp02";
        oldItems.Add(oldData2);


        List<NewData> newItems = new List<NewData>();

        NewData newData1 = new NewData();
        newData1.Name = "Test01";
        newData1.OriginalPath = "D:/Temp01";

        newItems.Add(newData1);

        NewData newData2 = new NewData();
        newData2.Name = "Test05";
        newData2.OriginalPath = "D:/Temp05";
        newItems.Add(newData2);


        oldItems = oldItems.Where(x => newItems != null && !newItems.Any(y => x.Name == y.Name && x.OriginalPath == y.OriginalPath)).ToList();

    }
}

class OldData
{
    public string Name { get; set; }
    public string OriginalPath { get; set; }
}

class NewData
{
    public string Name { get; set; }
    public string OriginalPath { get; set; }
}

【讨论】:

    【解决方案2】:

    1) 我会使用共享属性实现interface

    2) 我们让两个类都实现它(反正已经完成了)

    3) 我们为特定的interface 实现了一个EqualityComparer,它将仅从实现我们的interface 的两个对象中检查我们想要的属性

    这是一个实现示例:

    class Program
    {
        static void Main(string[] args)
        {
            OldData oldData = new OldData
            {
                Name = "Pizza",
                OriginalPath = "Pozza"
            };
    
            NewData newData = new NewData
            {
                Name = "Pizza",
                OriginalPath = "Pozza"
            };
    
            var comparer = new CommonDataComparer();
    
            bool areEqual = comparer.Equals(oldData, newData);
    
            Console.WriteLine(areEqual);
        }
    }
    
    public interface ICommonData
    {
        public string Name { get; set; }
        public string OriginalPath { get; set; }
    }
    
    public class OldData : ICommonData
    {
        public string Name { get; set; }
        public string OriginalPath { get; set; }
        //Old other properties
    }
    
    public class NewData : ICommonData
    {
        public string Name { get; set; }
        public string OriginalPath { get; set; }
        //New other properties
    }
    
    public class CommonDataComparer : IEqualityComparer<ICommonData>
    {
        public bool Equals([AllowNull] ICommonData x, [AllowNull] ICommonData y)
        {
            return ((x?.Name == y?.Name) && (x?.OriginalPath == y?.OriginalPath));
        }
    
        public int GetHashCode([DisallowNull] ICommonData obj)
        {
            return obj.Name.GetHashCode() + obj.OriginalPath.GetHashCode();
        }
    }
    

    输出:

    是的

    【讨论】:

      【解决方案3】:

      您正在比较字符串,因此 == 运算符可以正常工作。

      这是一个不使用 LINQ 的简单答案。 只是一个具有 2 个条件的 foreach 循环:

          for (int i = oldItems.Count - 1; i >= 0; i--)
          {
              OldData currentOldItem = oldItems[i] as OldData;
              foreach (var newItem in newItems) {
                  if (currentOldItem.Name == newItem.Name) {
                      if (currentOldItem.OriginalPath == newItem.OriginalPath) {
                          oldItems.RemoveAt(i);
                      } 
                  }
              }
          }
      

      【讨论】:

      • 在 foreach 中删除?值得怀疑
      • 感谢您的回答,但这样可能会遗漏某些值,对吗?因为比较是逐项完成的
      • 对不起,你完全正确。您可以使用反向 for 循环来实现您想要的。我将编辑我的答案。
      猜你喜欢
      • 1970-01-01
      • 2014-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-09
      • 2021-07-13
      相关资源
      最近更新 更多