我有一个名为FileRecordDto的DTO,其属性是字符串字典。该字典代表一个交易记录。值都是字符串,键是列名:
public class FileRecordDto
{
public IDictionary<string, string> Fields { get; internal set; }
= new Dictionary<string, string>();
}
我还有一个枚举包装类来表示列名
public class FieldName
{
public enum CRFS
{
Amount,
ActionDate,
ContractReference,
CycleDate,
}
}
给定FileRecordDtos的输入列表,我需要根据四个字段按唯一记录进行分组。我在StackOverflow上找到了一个standard方法来处理这个问题,但是在检查一个字符串数组时它似乎会中断:
var filteredRecords = originalRecords.GroupBy(x => new string[]
{
x.Fields[nameof(FieldName.CRFS.ContractReference)],
x.Fields[nameof(FieldName.CRFS.ActionDate)],
x.Fields[nameof(FieldName.CRFS.Amount)],
x.Fields[nameof(FieldName.CRFS.CycleDate)]
});
return filteredRecords.Select(y => y.First()).ToList();
运行时的IntelliSense检查显示两个不同记录的字符串数组看起来可能相同,但它们被视为不同的值。
我做错了什么?
答案 0 :(得分:2)
@Override
public void onBackPressed() {
Intent i = new Intent(this, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
答案 1 :(得分:0)
您需要定义自定义IEqualityComparer<TKey>
以按值而不是按引用比较数组。
这个的实现将是:
public class ArrayEqualityComparer<T> : IEqualityComparer<T[]>
{
public bool Equals(T[] x, T[] y)
{
return x.SequenceEqual(y);
}
public int GetHashCode(T[] array)
{
int hc = array.Length;
for (int i = 0; i < array.Length; ++i)
{
hc = unchecked(hc * 314159 + array[i].GetHashCode());
}
return hc;
}
}
用法:
var filteredRecords = originalRecords.GroupBy(new string[]
{
x.Fields[nameof(FieldName.CRFS.ContractReference)],
x.Fields[nameof(FieldName.CRFS.ActionDate)],
x.Fields[nameof(FieldName.CRFS.Amount)],
x.Fields[nameof(FieldName.CRFS.CycleDate)]
}, new ArrayEqualityComparer<string>());
如果字段数已修复,则可以使用匿名对象:
var filteredRecords = originalRecords.GroupBy(x => new
{
ContractReference = x.Fields[nameof(FieldName.CRFS.ContractReference)],
ActionDate = x.Fields[nameof(FieldName.CRFS.ActionDate)],
Amount = x.Fields[nameof(FieldName.CRFS.Amount)],
CycleDate = x.Fields[nameof(FieldName.CRFS.CycleDate)]
});
答案 2 :(得分:-1)
正如@mjwills所提到的,当我在没有new
部分的情况下尝试string[]
时,我只是缺少属性名称。所以这有效:
var filteredRecords = originalRecords.GroupBy(x => new
{
a = x.Fields[nameof(FieldName.CRFS.ContractReference)],
b = x.Fields[nameof(FieldName.CRFS.ActionDate)],
c = x.Fields[nameof(FieldName.CRFS.Amount)],
d = x.Fields[nameof(FieldName.CRFS.CycleDate)]
});
return filteredRecords.Select(y => y.First()).ToList();
为了完整起见,以下修复了我的问题,两个看似相似的字符串数组被视为唯一;我认为这是比较字符串指针而不是值。将GetHashCode值相加就像魅力一样:
var filteredRecords = originalRecords.GroupBy(x =>
x.Fields[nameof(FieldName.CRFS.ContractReference)].GetHashCode()
+ x.Fields[nameof(FieldName.CRFS.ActionDate)].GetHashCode()
+ x.Fields[nameof(FieldName.CRFS.Amount)].GetHashCode()
+ x.Fields[nameof(FieldName.CRFS.CycleDate)].GetHashCode());
return filteredRecords.Select(y => y.First()).ToList();