gpt4 book ai didi

c# - Linq 以非常规方式删除 ASP.NET WEB API 中的重复项

转载 作者:太空宇宙 更新时间:2023-11-03 13:27:20 24 4
gpt4 key购买 nike

这是我的模型:

 public class Combination
{
public int Id { get; set; }
public int CombOne{ get; set; }
public int CombTwo{ get; set; }

}

我想编写一个 LINQ 语句来提取 Combination 类的那些实例,其中包含属性 CombOne 和 CombTwo 的重复组合。因此,如果有如下三个实例:

Combination C1= new Combination{Id=1, CombOne=1, CombTwo=2};
Combination C2= new Combination{Id=2, CombOne=2, CombTwo=1};
Combination C3= new Combination{Id=3, CombOne=1, CombTwo=2};

Linq 语句应该返回 C2 和 C3 的列表,因为它们包含 CombOne 和 CombTwo 变量的重复组合,同时它应该保留原始实例 (C1)(不应返回 C1,因为它是第一个实例的组合。)

我用 foreach 循环得到了正确的结果。

List<Combination> invalid2 = new List<Combination>();
foreach (Combination g in list)// Gamelist.Match is a list of Combination type
{
if (invalid2.Contains(g))
continue;
List<Combination> invalid3 = (from r in list
where
((r != g) &&
(((r.CombOne == g.CombOne) && (r.CombTwo == g.CombTwo)) ||
((r.CombOne == g.CombTwo) && (r.CombTwo == g.CombOne))))
select r).ToList();
invalid2 = invalid2.Concat(invalid3).ToList();
}

我想只使用Linq语句得到结果以提高效率。我尝试了很多但没有得到想要的输出。预先感谢您的真诚努力

最佳答案

如果我对你的理解是正确的,你希望输出产生任何实例,其中包含以前见过的集合 { CombOne, CombTwo }。这意味着某种聚合。为此,您需要跟踪之前看到的实例并引用该集合以确保检查的每个后续元素都没有被看到。我将利用 Hashet.Add 不会添加已经在集合中的元素这一事实,并使用自定义比较器来确定 HashSet 中的相等性.

 var set = new HashSet<Combination>(new CombinationComparer());
var invalid = list.Aggregate(new List<Combination>(list.Count),
(a,c) =>
{
if (!set.Add(c))
{
a.Add(c);
}
return a;
});

在哪里

public class CombinationComparer : IEqualityComparer<Combination>
{
public bool Equals(Combination c1, Combination c2)
{
if (ReferenceEquals(c1,c2))
{
return true;
}

if (c1 == null || c2 == null)
{
return false;
}

return (c1.CombOne == c2.CombOne && c1.CombTwo == c2.CombTwo)
|| (c1.CombOne == c2.CombTwo && c1.CombTwo == c2.CombOne);
}

public int GetHashCode(Combination c)
{
if (c == null)
{
return 0;
}

unchecked
{
// it's important that this be commutative so we don't
// do the usual multiply by a prime to differentiate
// them.
return CombOne.GetHashCode() + CombTwo.GetHashCode();
}

}
}

我会注意到,这并不比使用循环并边走边构建结果更有效,而且可读性稍差:

var set = new HashSet<Combination>(new CombinationComparer());
var invalid = new List<Combination>(list.Count);
foreach (var item in list)
{
if (set.Add(item)) continue;

invalid.Add(item);
}

在这两种情况下,作为奖励,您都会获得存储在 set 中的独特且首次出现的重复集。使用 HashSet 在这两种情况下都非常有效,因为您只遍历列表一次并且 HashSet.AddList.Add 都是平均值情况 O(1) - 特别是当我们将列表的大小预先设置为最初的最大大小时。

我会注意到,如果您真正想要的是删除重复项,您可以简单地将比较器与 Distinct 一起使用。这与上面的类似,只是您不保留无效列表。

var unique = list.Distinct(new CombinationComparer());

我在 http://dotnetfiddle.net/YoApPu 创建了一个工作 fiddle

关于c# - Linq 以非常规方式删除 ASP.NET WEB API 中的重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21950224/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com