繁体   English   中英

检查集合 c# 中是否存在元素

[英]Check for existence of an element in the collection c#

我试图阻止在 C# 中已经存在的列表中添加一个项目。 下面的代码循环遍历数据表行。 如您所见,行的类型为List<CubeReportRow>

数据表行确实包含重复项。 我需要检查数据表中的 rowName 是否已经在List<CubeReportRow>类型的 object 行中。 请查看我在 foreach 循环中设置的条件。 当我尝试按行名检查时,它说无法将字符串转换为 CubeReportRow 类型。 如果我检查 if (.rows,Contains(row[0])).there 没有编译错误,但我不工作。 如何检查它在行集合中的存在。

Class CubeReportRow

 public class CubeReportRow
    {
        public string RowName { get; set; }
        public string RowParagraph { get; set; }
        public int ReportSection { get; set; }
    }

C# 方法

 public virtual IList<CubeReportRow> TransformResults(CubeReport report,DataTable dataTable)
        {
            if (dataTable.Rows.Count == 0 || dataTable.Columns.Count == 0)
                return new List<CubeReportRow>();

            var rows = new List<CubeReportRow>();
            var columns = columnTransformer.GetColumns(dataTable);

            foreach (DataRow row in dataTable.Rows)
            {
                
                var rowName = row[0].ToString();
                if (!rows.Contains(rowName))
                {
                    var values =
                        cubeReportValueFactory.CreateCubeReportValuesForRow(dataTable, row, rowName, columns, report);

                    var reportRow = new CubeReportRow(row[3].ToString(), row[2].ToString(), row[1].ToString(), values);
                    rows.Add(reportRow);
                }
            }

            return rows;
        }

您可以将Dictionary<string, CubeReportRow>用于您的rows变量,并使用ContainsKey检查键( rowName )是否存在:

var rows = new Dictionary<string, CubeReportRow>();
if (!rows.ContainsKey(rowName))
{
    // ...
    rows.Add(rowName, reportRow);
}

// ...

return rows.Values.ToList();

这并不是一个真正的答案,因为我相信Guru Strons的答案就足够了。

但是,有很多方法可以做到这一点,这将产生不同的性能和复杂性,具体取决于您的数据/重复率(并且不限于以下内容)。

字典

var rows = new Dictionary<string, CubeReportRow>();
foreach (var dataRow in _data)
   if (!rows.ContainsKey(dataRow.RowName))
      rows.Add(dataRow.RowName, dataRow);
return rows.Values.ToList();

哈希集

var hashSet = new HashSet<string>(_data.Length);
return _data.Where(x => hashSet.Add(x.RowName)).ToList();

通过...分组

return _data.GroupBy(x => x.RowName).Select(x => x.First()).ToList();

IEqualityComparer

public class SomeComparer : IEqualityComparer<CubeReportRow> {
   public bool Equals(CubeReportRow x, CubeReportRow y) {
      return x.RowName == y.RowName;
   }
   public int GetHashCode(CubeReportRow obj) {
      return obj.RowName.GetHashCode();
   }
}

...

return _data.Distinct(new SomeComparer()).ToList();

基准

配置

BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19041.746 (2004/?/20H1)
Intel Core i7-7700 CPU 3.60GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=5.0.102
  [Host]        : .NET Core 5.0.2 (CoreCLR 5.0.220.61120, CoreFX 5.0.220.61120), X64 RyuJIT
  .NET Core 5.0 : .NET Core 5.0.2 (CoreCLR 5.0.220.61120, CoreFX 5.0.220.61120), X64 RyuJIT

Job=.NET Core 5.0  Runtime=.NET Core 5.0

结果

方法 意思是 错误 标准差
字典 205.3 我们 4.06 我们 5.69 我们
哈希集 237.6 美元 4.73 我们 10.19 我们
清楚的 299.4 美元 5.24 我们 4.90 我们
通过...分组 451.3 我们 5.28 我们 4.68 我们

完整的测试代码

[SimpleJob(RuntimeMoniker.NetCoreApp50)]
public class Test
{
   private CubeReportRow[] _data;


   public class CubeReportRow
   {
      public string RowName { get; set; }
      public string RowParagraph { get; set; }
      public int ReportSection { get; set; }
   }

   [GlobalSetup]
   public void Setup()
   {
      var r = new Random(32);
      _data = new CubeReportRow[10000];
      for (int i = 0; i < 10000; i++)
         _data[i] = new CubeReportRow() {RowName = r.Next(100).ToString()};

   }

   [Benchmark]
   public List<CubeReportRow> Dictionary()
   {
      var rows = new Dictionary<string, CubeReportRow>();
      foreach (var dataRow in _data)
         if (!rows.ContainsKey(dataRow.RowName))
            rows.Add(dataRow.RowName, dataRow);
      return rows.Values.ToList();
   }

   [Benchmark]
   public List<CubeReportRow> HashSet()
   {
      var hashSet = new HashSet<string>(_data.Length);
      return _data.Where(x => hashSet.Add(x.RowName)).ToList();

   }

   public class SomeComparer : IEqualityComparer<CubeReportRow>
   {
      public bool Equals(CubeReportRow x, CubeReportRow y)
      {
         return x.RowName == y.RowName;
      }

      public int GetHashCode(CubeReportRow obj)
      {
         return obj.RowName.GetHashCode();
      }
   }

   [Benchmark]
   public List<CubeReportRow> Distinct()
   {
      return _data.Distinct(new SomeComparer()).ToList();

   }

   [Benchmark]
   public List<CubeReportRow> GroupBy()
   {
      return _data.GroupBy(x => x.RowName).Select(x => x.First()).ToList();

   }
}

注意:如果您对性能感兴趣,请使用真实数据自行运行这些基准测试。

LINQ 非常适合这个(就易于阅读的代码而言)

在文件的顶部: using System.Linq;

然后: if (.rows.Any(r => r.RowName == rowName)) (替换if (.rows.Contains(rowName))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM