[英]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.