Linq RemoveAll删除所有项

本文关键字:删除 RemoveAll Linq | 更新日期: 2023-09-27 18:05:01

我有一个集合newLinks的数据表与几个记录。下面是表结构

LinkSysId | LinkId | Col1 | Col2
1           1        str    str1
2           1        str5   str4 
3           2        str2   str3
4           2        str6   str7

我想做一个linq查询,它将迭代集合并只留下前1个不同的LinkId记录:

LinkSysId | LinkId | Col1 | Col2
1           1        str    str 
3           2        str3   str3

我试着这样做

newLinks.RemoveAll(rowComp => newLinks.Any(rowDel => 
                   rowComp["linkId"].ToString() == rowDel["linkId"].ToString() 
                   &&  rowComp["linkSysId"].ToString() != rowDel["linkSysId"].ToString()));

但是它从集合中删除了所有项?感谢您的帮助

Linq RemoveAll删除所有项

有实现DistinctBy()的LINQ扩展库,这就是你正在寻找的。然而,这一小段代码利用了hashset上的Add()方法,如果已经添加了相同的项,则返回false:

var foundIds = new HashSet<int>();
var FirstLinkId = newLinks.Where(row=>foundIds.Add(row.LinkId)).ToList();

"create new"方法:

DataTable keepTheseRows = table.AsEnumerable()
    .GroupBy(r => r.Field<int>("LinkId"))
    .Select(g => g.First())  // takes the first of each group arbitrarily
    .CopyToDataTable();

正如Tormod所说,最好的方法是使用DistinctBy()实现。

(特别是,看看Tormod的实现,你会发现它实际上与下面的DistinctByImpl()方法相同,所以这个答案应该被认为是他的扩展。)

如果您使用DistinctBy(),解决方案就变得非常简单:

var uniques = list.DistinctBy(item => item.LinkId);

一个很好的DistinctBy()实现可以在Jon Skeet的MoreLinq库中找到,该库也可以在NuGet上找到。

作为一个例子,下面是使用MoreLinq的DistinctBy()实现的副本的实现。不要使用这些代码-使用NuGet下载原始注释代码。

using System;
using System.Linq;
using System.Collections.Generic;
namespace Demo
{
    public static class Program
    {
        public static void Main(string[] args)
        {
            List<Test> list = new List<Test>
            {
                new Test(1, 1),
                new Test(2, 1),
                new Test(3, 2),
                new Test(4, 2)
            };
            var uniques = list.DistinctBy(item => item.LinkId);
            foreach (var item in uniques)
            {
                Console.WriteLine(item);
            }
        }
    }
    public class Test
    {
        public Test(int linkSysId, int linkId)
        {
            LinkSysId = linkSysId;
            LinkId = linkId;
        }
        public override string ToString()
        {
            return string.Format("LinkSysId = {0}, LinkId = {1}", LinkSysId, LinkId);
        }
        public int LinkSysId;
        public int LinkId;
    }
    static class EnumerableExt
    {
        public static IEnumerable<TSource> DistinctBy<TSource, TKey>
            (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
        {
            return source.DistinctBy(keySelector, null);
        }
        public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source,
            Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
        {
            if (source == null) throw new ArgumentNullException("source");
            if (keySelector == null) throw new ArgumentNullException("keySelector");
            return DistinctByImpl(source, keySelector, comparer);
        }
        private static IEnumerable<TSource> DistinctByImpl<TSource, TKey>(IEnumerable<TSource> source,
            Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
        {
            var knownKeys = new HashSet<TKey>(comparer);
            return source.Where(element => knownKeys.Add(keySelector(element)));
        }
    }
}