在 C# 中删除单个数据集中相对于另一个数据集的重复项
Delete duplicates in a single dataset relative to another one in C#
我是 C# 新手。
尝试删除 CollectionIn1 中的重复项,但它不起作用。 CollectionIn 中没有删除任何重复项。
澄清一下,collectionIn 有 [A,B,C,D],collectionIn2 有 [A,B,C]。
所以我想删除 collectionIn
中的值 (A,B,C)
for (int i = 0; i < CollectionIn.Rows.Count; i++) {
string value1 = CollectionIn.Rows[i].ItemArray[0].ToString().ToLower();
for (int i2 = 0; i2 < CollectionIn2.Rows.Count; i2++) {
string value2 = CollectionIn2.Rows[i2].ItemArray[0].ToString().ToLower();
if (value1 == value2) {
//Remove value1 when value1 == value2
CollectionIn.Rows[i].Delete(); <--- Trying to delete when there is duplicate in both collections
CollectionIn.AcceptChanges();
}
}
//CollectionOut.Rows.Add(value1);
}
我对此做了一些修改link
http://www.rpaforum.net/threads/how-to-compare-two-excel-sheet-using-c-code-in-blueprism.897/
您可以使用 Distinct 运算符删除重复项。
要从类似 IList<> 的对象中删除重复项,您可以这样做:
yourList.RemoveAll( yourList.Except( yourList.Distinct() ) );
foreach(var row in CollectionIn.Rows.Cast<DataRow>()
.Where(x => CollectionIn2.Rows.Cast<DataRow>()
.Any(y => y[0].ToString().ToLower() == x[0].ToString().ToLower())))
{
row.Delete();
}
CollectionIn.AcceptChanges();
不是最好的性能,但它可以工作并且易于阅读。
此外,由于在遍历集合时修改了集合,因此您的代码中存在错误。
有效且易于理解。
List<string> List1 = new List<string> { "A", "B", "C", "D" };
List<string> List2 = new List<string> { "A", "B", "C" };
List<string> ListTemp = new List<string>();
foreach (string str1 in List1)
{
foreach (string str2 in List2)
{
if (str1 == str2)
{
ListTemp.Add(str1);
}
}
}
foreach (string temp in ListTemp)
{
List1.Remove(temp);
}
比较两个集合的复杂度为 O(n2)。这是不好的。如果你有一个初始哈希查找,你可以得到改进。
var Set1 = new Dictionary<string, int>();
//Prehash all values in the set that won't be deleted from
for (int i = 0; i < CollectionIn.Rows.Count; i++)
{
string value1 = CollectionIn.Rows[i].ItemArray[0].ToString().ToLower();
Set1.Add(value1, i);
}
//Loop over the other set
for (int i2 = 0; i2 < CollectionIn2.Rows.Count; i2++)
{
string value2 = CollectionIn2.Rows[i2].ItemArray[0].ToString().ToLower();
int foundIndex;
if (Set1.TryGetValue(value2, out foundIndex) == false)
continue;
//Remove value1 when value1 == value2
CollectionIn.Rows[foundIndex].Delete();
}
CollectionIn.AcceptChanges(); //It's probably best to save changes last as a single call
我散列 CollectionIn,然后迭代 CollectionIn2。这意味着我需要一本字典,这样我就有了用于删除的 CollectionIn 索引。如果反过来,CollectionIn2 被散列,它只需要是一个散列集,它会更好,因为它能够处理 CollectionIn 集中的内部重复,因此:
var Set2 = new HashSet<string>();
//Prehash all values in one set (ideally the larger set)
for (int i2 = 0; i2 < CollectionIn2.Rows.Count; i2++)
{
string value2 = CollectionIn2.Rows[i2].ItemArray[0].ToString().ToLower();
if (Set2.Contains(value2))
continue; //Duplicate value
else
Set2.Add(value2);
}
//Loop over the other set
for (int i1 = 0; i1 < CollectionIn.Rows.Count; i1++)
{
string value1 = CollectionIn.Rows[i1].ItemArray[0].ToString().ToLower();
if (Set2.Contains(value1) == false)
continue;
//Remove value1 when value1 == value2
CollectionIn.Rows[i1].Delete();
}
CollectionIn.AcceptChanges(); //It's probably best to save changes last as a single call
此模式适用于许多数据集类型(包括列表、数组等)。当然,如果你能在同一个数据库上为远程数据集编写SQL,那就更好了。
如果您喜欢 lambda 函数,它应该看起来像这样:
var alreadyInSet2 = new HashSet<string>(CollectionIn2.Rows.Cast<DataRow>()
.Select(x => x[0].ToString().ToLower()));
CollectionIn.Rows.Cast<DataRow>()
.Where(y => alreadyInSet2.Contains(y[0].ToString().ToLower()) == false)
.ToList() //I think you technically need this before calling ForEach
.ForEach(y => y.Delete());
CollectionIn.AcceptChanges();
另请参阅: - 更多 time/work 可以进入更广泛的答案安排和性能增强。
mylist2 = mylist2.Distinct().ToList();
mylist1.RemoveAll(item => mylist2.Contains(item));
我是 C# 新手。 尝试删除 CollectionIn1 中的重复项,但它不起作用。 CollectionIn 中没有删除任何重复项。
澄清一下,collectionIn 有 [A,B,C,D],collectionIn2 有 [A,B,C]。
所以我想删除 collectionIn
中的值 (A,B,C)for (int i = 0; i < CollectionIn.Rows.Count; i++) {
string value1 = CollectionIn.Rows[i].ItemArray[0].ToString().ToLower();
for (int i2 = 0; i2 < CollectionIn2.Rows.Count; i2++) {
string value2 = CollectionIn2.Rows[i2].ItemArray[0].ToString().ToLower();
if (value1 == value2) {
//Remove value1 when value1 == value2
CollectionIn.Rows[i].Delete(); <--- Trying to delete when there is duplicate in both collections
CollectionIn.AcceptChanges();
}
}
//CollectionOut.Rows.Add(value1);
}
我对此做了一些修改link http://www.rpaforum.net/threads/how-to-compare-two-excel-sheet-using-c-code-in-blueprism.897/
您可以使用 Distinct 运算符删除重复项。
要从类似 IList<> 的对象中删除重复项,您可以这样做:
yourList.RemoveAll( yourList.Except( yourList.Distinct() ) );
foreach(var row in CollectionIn.Rows.Cast<DataRow>()
.Where(x => CollectionIn2.Rows.Cast<DataRow>()
.Any(y => y[0].ToString().ToLower() == x[0].ToString().ToLower())))
{
row.Delete();
}
CollectionIn.AcceptChanges();
不是最好的性能,但它可以工作并且易于阅读。
此外,由于在遍历集合时修改了集合,因此您的代码中存在错误。
有效且易于理解。
List<string> List1 = new List<string> { "A", "B", "C", "D" };
List<string> List2 = new List<string> { "A", "B", "C" };
List<string> ListTemp = new List<string>();
foreach (string str1 in List1)
{
foreach (string str2 in List2)
{
if (str1 == str2)
{
ListTemp.Add(str1);
}
}
}
foreach (string temp in ListTemp)
{
List1.Remove(temp);
}
比较两个集合的复杂度为 O(n2)。这是不好的。如果你有一个初始哈希查找,你可以得到改进。
var Set1 = new Dictionary<string, int>();
//Prehash all values in the set that won't be deleted from
for (int i = 0; i < CollectionIn.Rows.Count; i++)
{
string value1 = CollectionIn.Rows[i].ItemArray[0].ToString().ToLower();
Set1.Add(value1, i);
}
//Loop over the other set
for (int i2 = 0; i2 < CollectionIn2.Rows.Count; i2++)
{
string value2 = CollectionIn2.Rows[i2].ItemArray[0].ToString().ToLower();
int foundIndex;
if (Set1.TryGetValue(value2, out foundIndex) == false)
continue;
//Remove value1 when value1 == value2
CollectionIn.Rows[foundIndex].Delete();
}
CollectionIn.AcceptChanges(); //It's probably best to save changes last as a single call
我散列 CollectionIn,然后迭代 CollectionIn2。这意味着我需要一本字典,这样我就有了用于删除的 CollectionIn 索引。如果反过来,CollectionIn2 被散列,它只需要是一个散列集,它会更好,因为它能够处理 CollectionIn 集中的内部重复,因此:
var Set2 = new HashSet<string>();
//Prehash all values in one set (ideally the larger set)
for (int i2 = 0; i2 < CollectionIn2.Rows.Count; i2++)
{
string value2 = CollectionIn2.Rows[i2].ItemArray[0].ToString().ToLower();
if (Set2.Contains(value2))
continue; //Duplicate value
else
Set2.Add(value2);
}
//Loop over the other set
for (int i1 = 0; i1 < CollectionIn.Rows.Count; i1++)
{
string value1 = CollectionIn.Rows[i1].ItemArray[0].ToString().ToLower();
if (Set2.Contains(value1) == false)
continue;
//Remove value1 when value1 == value2
CollectionIn.Rows[i1].Delete();
}
CollectionIn.AcceptChanges(); //It's probably best to save changes last as a single call
此模式适用于许多数据集类型(包括列表、数组等)。当然,如果你能在同一个数据库上为远程数据集编写SQL,那就更好了。
如果您喜欢 lambda 函数,它应该看起来像这样:
var alreadyInSet2 = new HashSet<string>(CollectionIn2.Rows.Cast<DataRow>()
.Select(x => x[0].ToString().ToLower()));
CollectionIn.Rows.Cast<DataRow>()
.Where(y => alreadyInSet2.Contains(y[0].ToString().ToLower()) == false)
.ToList() //I think you technically need this before calling ForEach
.ForEach(y => y.Delete());
CollectionIn.AcceptChanges();
另请参阅:
mylist2 = mylist2.Distinct().ToList();
mylist1.RemoveAll(item => mylist2.Contains(item));