我想对某些列进行分组分组,但是它们可能会有所不同,并且我不想对将要分组的字段进行硬编码。
我尝试过:
users.GroupBy(groupingColumnIndexes.Select(a => x.ColumnValues[a]))
...
List<Row> users = new List<Row>()
{
new Row("John", "Doe", "10"),
new Row("John", "Doe", "45"),
new Row("Will","Smith", "26"),
new Row("Will", "Smith", "52"),
new Row("Julius", "Cesar", "23")
};
List<int> groupingColumnIndexes = new List<int>() { 0, 1 };
List<User> output = users
.GroupBy(x => {
// INFO: if I'd return groupingColumns code would not group users correctly.
var groupingColumns = groupingColumnIndexes.Select(a => x.ColumnValues[a]);
string col1Value = x.ColumnValues[0];
string col2Value = x.ColumnValues[1];
// Result below is working, but I would rather build more dynamic version.
var result = new { col1Value, col2Value };
return result;
})
.Select(x => new User
{
Name = string.Join(",", x.Key),
Age = (int)x.Sum(a => int.Parse(a.ColumnValues[2])),
LastName = string.Empty
}).ToList();
.NET小提琴:https://dotnetfiddle.net/cPuafD
预期: 约翰·多伊55 威尔·史密斯78 朱利叶斯·塞萨尔23
使用GroupBy(list)时的实际值: 约翰,母鹿10 约翰,母鹿45 威尔·史密斯26 威尔·史密斯52 撒撒利亚朱利叶斯23
答案 0 :(得分:1)
我得到了改进,@ Xiaoy312的回答使它看起来更容易理解。
public class StringColumnEqualityComparer : IEqualityComparer<List<string>>
{
public StringColumnEqualityComparer()
{
}
public bool Equals(List<string> x, List<string> y) {
bool output = x.SequenceEqual(y);
return output;
}
public int GetHashCode(List<string> obj)
{
int output = obj.Aggregate(13, (hash, y) => hash * 7 + y?.GetHashCode() ?? 0);
return output;
}
}
用法:
List<Row> users = new List<Row>()
{
new Row("John", "Doe", "10"),
new Row("John", "Doe", "45"),
new Row("Will","Smith", "26"),
new Row("Will", "Smith", "52"),
new Row("Julius", "Cesar", "23")
};
List<int> groupingColumnIndexes = new List<int>() { 0, 1 };
List<User> output = users
.GroupBy(x =>
groupingColumnIndexes.Select(c => x.ColumnValues[c]).ToList(),
new StringColumnEqualityComparer()
)
.Select(x => new User
{
Name = string.Join(',', x.Key),
Age = (int)x.Sum(a => int.Parse(a.ColumnValues[2])),
LastName = string.Empty
}).ToList();
答案 1 :(得分:0)
您需要为列IEqualityComparer
实现GroupBy
:
class LambdaComparer<T> : IEqualityComparer<T>
{
private readonly Func<T, T, bool> equals;
private readonly Func<T, int> getHashCode;
public LambdaComparer(Func<T, T, bool> equals, Func<T, int> getHashCode)
{
this.equals = equals;
this.getHashCode = getHashCode;
}
public bool Equals(T x, T y) => equals(x, y);
public int GetHashCode(T obj) => getHashCode(obj);
}
var output = users
.GroupBy(
x => groupingColumnIndexes.Select(i => x.ColumnValues[i]).ToArray(),
new LambdaComparer<string[]>((a, b) => a.SequenceEqual(b), x => x.Aggregate(13, (hash, y) => hash * 7 + y?.GetHashCode() ?? 0))
)
.Select(g => new User
{
Name = g.Key[0],
LastName = g.Key[1],
Age = g.Sum(x => int.Parse(x.ColumnValues[2]))
})
.ToList();