Reputation: 1106
I have a data = List<Model>
, where Model
looks like this
public class Model{
public string String1 { get; set; }
public int Int1{ get; set; }
public int Int2{ get; set; }
public string String2 { get; set; }
public decimal Decimal1{ get; set; }
...
public decimal DecimalN{ get; set; }
}
I want to have average of each DecimalX
values group by String1
, Int1
, Int2
, but my problem is that sometimes I have two or more the same rows and only String2
is different, so I would like to do Distinct
, but doesn't work because of this String2
property. I was trying to change all values of String2
to null
or empty
string
var x = data.ForEach(x => x.String2= null);
but I receive error Cannot asign void to implicitly- typed variable.
Upvotes: 0
Views: 143
Reputation: 996
Just like Reniuz said that error occurs becaus forEach doesn't return anything (void).
Returning to your main problem, you mentioned that you need the average value for each Decimal.
For Decimal1 you can do something like this:
var b = list.GroupBy(g => new { g.String1, g.Int1, g.Int2 }).Select(r=> new {r.Key.String1, r.Key.Int1, r.Key.Int2, avgDecimal1 = r.Select(g=>g.Decimal1).Average()}).ToList();
First you need to Group by the elements that are going to be your keys (without String2 like you said) and after that, select those keys and the AVG of the elements of a determined property (e.g. Decimal1). You can add more AVG functions if you want (avgDecimal2, avgDecimal3, etc)
Upvotes: 1
Reputation: 182
I don't understand why you want distinct values. May be you can provide an example. One solution can be -
var result = data.GroupBy(x => new { x.String1, x.Int1, x.Int2 })
.Select(g => new
{
String1 = g.Key.String1,
Int1 = g.Key.Int1,
Int2 = g.Key.Int2,
AvgDecimal1 = g.Select(x => x.Decimal1).Average(),
AvgDecimal2 = g.Select(x => x.Decimal1).Average(),
AvgDecimalN = g.Select(x => x.Decimal1).Average()
}).ToList();
If you want distinct values you can add distinct before group by -
data.Select(d => new Model { String1 = d.String1, Int1 = d.Int1, Int2 = d.Int2, Decimal1 = d.Decimal1, Decimal2 = d.Decimal2, DecimalN = d.DecimalN }) //returning new collection with String2 as null
.Distinct()
First solution produces following result -
Upvotes: 0
Reputation: 5878
you want to start with projecting your results with the values you want to work with or in the way you want to work with them.
var query = source.Select(e => new
{
e.String1,
e.Int1,
e.Int2,
e.Decimal1,
});
Just omit the properties you don't want.
// or go straight to your average
var sum = data.GroupBy(e => new
{
e.String1,
e.Int1,
e.Int2,
e.Decimal1,
}).Average(e => e.Key.Decimal1);
Upvotes: 0
Reputation: 11820
ForEach does not return anything - it's is void method, so your assignment to x
is not valid.
Instead of this:
var x = data.ForEach(x => x.String2= null);
You should do like this:
data.ForEach(x => x.String2= null);
Upvotes: 1