我有一个包含数据的列表,有时它包含重复的行,我想删除我在代码下面使用的重复行
num = numDetailsTemp.Distinct().ToList();
var query = num.GroupBy(o => new { o.Number })
.Select(group =>
new
{
Name = group.Key,
Numbers = group.OrderByDescending(x => x.Date)
})
.OrderBy(group => group.Numbers.First().Date);
List<NumberDetails> numTemp = new List<NumberDetails>();
foreach (var group in query)
{
foreach (var numb in group.Numbers)
{
numTemp.Add(numb);
break;
}
}
num = numTemp;
下图显示了列表中的重复值。
当我应用删除重复项时,它会给我输出
但是我要删除不包含alter no或id证明和日期的行,如第一张图片第一行所示,不包含AlterNo和ID证明和日期,而第二行包含该行,因此我要删除第一行并仅显示第二行。日期是必须检查的,之后是AlterNo和ID证明。
答案 0 :(得分:2)
您可以使用Distinct
运算符消除重复项。首先,您需要定义一个实现IEqualityComparer
接口的比较器类,然后将其传递给您方法中的不同运算符。
internal class NumberDetailsComparer : IEqualityComparer<NumberDetails>
{
public bool Equals(NumberDetails x, NumberDetails y)
{
if (\* Set of conditions for equality matching *\)
{
return true;
}
return false;
}
public int GetHashCode(Student obj)
{
return obj.Name.GetHashCode(); // Name or whatever unique property
}
}
这是使用方法:
var distinctRecords = source.Distinct(new NumberDetailsComparer());
您需要做的就是定义比较器类的条件。 希望这能解决您的问题。
此链接对于完整的示例可能有用:
答案 1 :(得分:2)
您可以尝试以下操作:
var group =
list
.GroupBy(r => r.Number)
.SelectMany(g => g) //flatten your grouping and filter where you have alterno and id
.Where(r => !string.IsNullOrEmpty(r.AlterNo) && !string.IsNullOrEmpty(r.Id))
.OrderByDescending(r=>r.Date)
.ToList();
答案 2 :(得分:0)
因此,您有一个NumberDetails
的序列,以及一个有关何时考虑NumberDetails
相等的定义。
一旦发现哪个NumberDetails
相等,就想消除重复项,但重复项除外:重复项的值分别为AlterNo
和IdProof
。
las,如果没有重复的AlterNo
和IdProof
值,则您没有指定所需的内容。如果有多个重复的值分别为AlterNo
和IdProof
的内容,您也不需要什么。
但是让我们假设,如果其中有多个项目,则您不在乎:只需选择一个,因为它们仍然是重复项。
根据您的要求,您谈论重复项。因此,让我们编写一个实现您的平等要求的类:
class NumberDetailEqualityComparer : IEqualityComparer<NumberDetail>
{
public static IEQualityComparer<NumberDetail> Default {get;} = new NumberDetaulEqualityComparer();
public bool Equals(NumberDetail x, NumberDetail y)
{
if (x == null) return y == null; // true if both null
if (y == null) return false; // because x not null and y null
if (Object.ReferenceEquals(x, y) return true; // because same object
if (x.GetType() != y.GetType()) return false; // because not same type
// by now we are out of quick checks, we need a value check
return x.Number == y.Number
&& x.FullName == y.FullName
&& ...
// etc, such that this returns true if according your definition
// x and y are equal
}
您还需要实现GetHashCode。您可以返回任何您想要的东西,只要您 确定如果x和y相等,则它们返回相同的HashCode 此外,如果x和y不相等,将会更有效率 那么使用不同的HashCode的可能性就很大。
类似的东西:
public int GetHashCode(NumberDetail numberDetail)
{
const int prime1 = 12654365;
const int prime2 = 54655549;
if (numberDetail == null) return prime1;
int hash = prime1;
unsafe
{
hash = prime2 * hash + numberDetail.Number.GetHashCode();
hash = prime2 * hash + numberDetail.FullName.GetHashCode();
hash = prime2 * hash + numberDetail.Date.GetHashCode();
...
}
return hash;
当然,您必须在询问HashCode之前检查是否有任何属性等于NULL。
很显然,在平等的情况下(因此在GetHashCode中),您不会查看AlterNo
或IdProof
。
在精确定义了两个NumberDetails
相等的对象后,就可以将相等的NumberDetails
组组成
var groupsEqualNumberDetails = numberDetails.GroupBy(
// keySelector: make groups with equal NumberDetails:
numberDetail => numberDetail,
// ResultSelector: take the key and all NumberDetails thas equal this key:
// and keep the first one that has values for AlterNo and IdProof
(key, numberDetailsEqualToKey) => numberDetailsEqualToKey
.Where(numberDetail => numberDetail.AlterNo != null
&& numberDetail.IdProof != null)
.FirstOrDefault(),
// KeyComparer: when do you consider two NumberDetails equal?
NumberDetailEqualityComparer.Default;
}