Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 根据条件防止阵列中的重复项_C#_.net_Linq_Delegates - Fatal编程技术网

C# 根据条件防止阵列中的重复项

C# 根据条件防止阵列中的重复项,c#,.net,linq,delegates,C#,.net,Linq,Delegates,我有一个数字数组,我需要防止重复。对于数组中大于0的每个数字,我需要删除除一个以外的所有重复项。例如,如果输入为[0,0,0,1,1,1,1,1,2,2],则输出应为:[0,0,0,1,2]。有人能帮我吗?我尝试了下面的代码,但得到的结果如下[0,1,2] Results.GroupBy(item => item.id).Select(x => x.First()); 输入和预期输出的另一个示例: 输入:{[id=0,Name=“test0”],[id=0,Name=“test0”

我有一个数字数组,我需要防止重复。对于数组中大于
0
的每个数字,我需要删除除一个以外的所有重复项。例如,如果输入为[0,0,0,1,1,1,1,1,2,2],则输出应为:[0,0,0,1,2]。有人能帮我吗?我尝试了下面的代码,但得到的结果如下[0,1,2]

Results.GroupBy(item => item.id).Select(x => x.First());
输入和预期输出的另一个示例:

输入:{[id=0,Name=“test0”],[id=0,Name=“test0”],[id=1,Name=“test1”],[id=1,Name=“test1”],[id=1,Name=“test1”],[id=2,Name=“test2”],[id=2,Name=“test2”]}
输出:{[id=0,Name=“test0”],[id=0,Name=“test0”],[id=1,Name=“test1”],[id=2,Name=“test2”]}

您可以编写自己的扩展方法,其工作原理与内置LINQ方法类似:

public static class Extensions
{
    public static IEnumerable<T> DistinctWhere<T>(this IEnumerable<T> input, Func<T,bool> predicate)
    {
        HashSet<T> hashset = new HashSet<T>();
        foreach(T item in input)
        {
            if(!predicate(item))
            {
                yield return item;
                continue;
            }
            
            if(!hashset.Contains(item))
            {
                hashset.Add(item);
                yield return item;
            }
        }
    }
}
在线演示:

编辑:如果要使用列表中对象的属性(如ID属性),可以对该方法添加一些细微的修改:

public static class Extensions
{
    public static IEnumerable<T> DistinctWhere<T,T2>(this IEnumerable<T> input, Func<T,T2> selector, Func<T2,bool> predicate)
    {
        HashSet<T2> hashset = new HashSet<T2>();
        foreach(T item in input)
        {
            T2 value = selector.Invoke(item);
            if(!predicate.Invoke(value))
            {
                yield return item;
                continue;
            }

            if(!hashset.Contains(value))
            {
                hashset.Add(value);
                yield return item;
            }
        }
    }
}

@John我想他们的意思是要删除重复项>0是的,我希望需要3个零来避免。您可以根据值分组,然后根据值只取一个或全部
list.GroupBy(x=>x)。SelectMany(grp=>grp.Key>0?grp.Take(1):grp)
注意,即使重复项不是像您的示例那样都在一行中,也会删除它们。如果零分散在整个列表中,您希望输出是什么,比如:
0,0,0,1,1,0,1,2,2,0
.related:项目的OPs集合似乎有一个他们正在筛选的Id属性,如果他们希望结果是项目而不是Id,那么如果没有一些更改,这将无法工作,因此它将散列Id而不是实际的项目。@juharr:这很容易实现。我添加了一个这样做的示例。“错误CS0246找不到类型或命名空间名称'T2'(是否缺少using指令或程序集引用?)”顺便说一句,我将使用名称
T
T2
,而不是
TSource
TKey
,而不是
选择器,
按键选择器
。此外,在接受选择器时,可能需要一个额外的参数
IEqualityComparer keyComparer
public static class Extensions
{
    public static IEnumerable<T> DistinctWhere<T,T2>(this IEnumerable<T> input, Func<T,T2> selector, Func<T2,bool> predicate)
    {
        HashSet<T2> hashset = new HashSet<T2>();
        foreach(T item in input)
        {
            T2 value = selector.Invoke(item);
            if(!predicate.Invoke(value))
            {
                yield return item;
                continue;
            }

            if(!hashset.Contains(value))
            {
                hashset.Add(value);
                yield return item;
            }
        }
    }
}
TypeWithId[] input = new TypeWithId[]
{
    new TypeWithId { ID = 0 } , 
    new TypeWithId { ID = 0 } , //... also initialize the other items
};
TypeWithId[] result = input.DistinctWhere(x => x.ID, x => x > 0).ToArray();