You can use the following class to create a comparer that can compare sequences of items based on the values in those sequences, rather than based on the reference to the sequence:
public class SequenceComparer<T> : IEqualityComparer<IEnumerable<T>>
{
private IEqualityComparer<T> comparer;
public SequenceComparer(IEqualityComparer<T> comparer = null)
{
comparer = comparer ?? EqualityComparer<T>.Default;
}
public bool Equals(IEnumerable<T> x, IEnumerable<T> y)
{
return x.SequenceEqual(y, comparer);
}
public int GetHashCode(IEnumerable<T> sequence)
{
unchecked
{
int hash = 19;
foreach (var item in sequence)
hash = hash * 79 + comparer.GetHashCode(item);
return hash;
}
}
}
Once we have this we can transform your grouping selector so that it projects out a sequence of the items you are interested in, since it's not known at compile time. The Select
selector is largely unchanged.
var y = tb.AsEnumerable()
.GroupBy(row => listView2.Items.Cast<ListViewItem>()
.Select(item => row[item.Text]), new SequenceComparer<object>())
.Select(group => new
{
Values = group.Key,
Total = group.Sum(s => s.Field<double>(listView3.Items[0].Text)),
});