Distinct rows by their values from sub list LINQ C# - c#

I would like to remove duplicate rows by their values from sub list using LINQ syntax. Below I attached code which does that by different way.
xxxxx xxxxxx xxxxxxx xxxxxxxxxxx xxxxxxxxxxxxxx xxxxxxxxxxxx xxxxxxxxxx xxxxxxxxxxxxxxxxxx
List<ZRowCollection> zListCollection = new List<ZRowCollection>();
zListCollection = zListCollection.OrderBy(p => p.P).ToList();
int i1 = 1;
foreach (var item in zListCollection.ToList())
{
var subList1 = item.XRowModified.Select(p => p).ToList();
foreach (var item2 in zListCollection.Skip(i1).ToList())
{
var subList2 = item2.XRowModified.Select(p => p).ToList();
int i = 0;
foreach (var item3 in subList1)
{
var t2 = subList2.Select(p => p.Average).ToList();
decimal average = t2[i];
if (item3.Average == average)
{
i++;
}
else break;
}
if (i == item2.XRowModified.Count)
{
zListCollection.Remove(item2);
}
}
i1++;
}
properties
class XRowModified
{
public decimal Id { get; set; }
public decimal Open { get; set; }
public decimal High { get; set; }
public decimal Low { get; set; }
public decimal Close { get; set; }
public DateTime Time { get; set; }
public decimal Average { get; set; }
}
class ZRowCollection
{
public ZRowCollection()
{
this.XRowModified = new HashSet<XRowModified>();
}
public int P { get; set; }
public int High { get; set; }
public int Low { get; set; }
public virtual ICollection<XRowModified> XRowModified { get; set; }
}
expected input/output,
as a comparer column Average in List<XRowModified>
List<ZRowCollection> zListInput = new List<ZRowCollection>(){
new ZRowCollection(){P = 0,High = 4,Low = 0, XRowModified = new List<XRowModified>(){
new XRowModified(){ Id = 1550, Open = 1.22M,High = 1.24M,Low = 1.21M,Close = 1.23M,Average = 1.225M,
Time = new DateTime(2012, 11, 9, 12, 23, 23, 222)},
new XRowModified(){ Id = 1551, Open = 1.20M,High = 1.24M,Low = 1.22M,Close = 1.20M,Average = 1.23M,
Time = new DateTime(2012, 11, 9, 12, 23, 25, 122)}}},
new ZRowCollection(){P = 1,High = 3,Low = 0, XRowModified = new List<XRowModified>(){
new XRowModified(){ Id = 1555, Open = 1.22M,High = 1.24M,Low = 1.21M,Close = 1.23M,Average = 1.225M,
Time = new DateTime(2012, 11, 9, 12, 23, 40, 422)},
new XRowModified(){ Id = 1556, Open = 1.20M,High = 1.25M,Low = 1.20M,Close = 1.20M,Average = 1.23M,
Time = new DateTime(2012, 11, 9, 12, 23, 46, 522)}}},
new ZRowCollection(){P = 2,High = 2,Low = 0, XRowModified = new List<XRowModified>(){
new XRowModified(){ Id = 1558, Open = 1.22M,High = 1.24M,Low = 1.21M,Close = 1.23M,Average = 1.225M,
Time = new DateTime(2012, 11, 9, 12, 30, 11, 622)},
new XRowModified(){ Id = 1559, Open = 1.20M,High = 1.24M,Low = 1.22M,Close = 1.20M,Average = 1.23M,
Time = new DateTime(2012, 11, 9, 12, 30, 12, 822)}}}
};
List<ZRowCollection> zListOutput = new List<ZRowCollection>(){
new ZRowCollection(){P = 0,High = 4,Low = 0, XRowModified = new List<XRowModified>(){
new XRowModified(){ Id = 1550, Open = 1.22M,High = 1.24M,Low = 1.21M,Close = 1.23M,Average = 1.225M,
Time = new DateTime(2012, 11, 9, 12, 23, 23, 222)},
new XRowModified(){ Id = 1551, Open = 1.20M,High = 1.24M,Low = 1.22M,Close = 1.20M,Average = 1.23M,
Time = new DateTime(2012, 11, 9, 12, 23, 25, 122)}}}
};

In this case I would consider writing a custom equality comparer, which could then be plugged in to the Distinct method. To do this you need two functions Equals and GetHashCode.
Note: It is important the GetHashCode returns the same hash for two equal objects as this is the first thing that Distinct checks.
From what I gather from your code two ZRow's are equal if their XRow's have the same sequence of averages, so our equality is that averageSequence1.SequenceEqual(averageSequence2) which would be implemented as so:
public class CustomComparer : IEqualityComparer<ZRowCollection>
{
public static CustomComparer Instance { get { return new CustomComparer(); } }
Int32 IEqualityComparer<ZRowCollection>.GetHashCode(ZRowCollection value)
{
//One could also use the sum of the averages here, but went for simplicity...
return value.XRowModified.Count;
}
Boolean IEqualityComparer<ZRowCollection>.Equals(ZRowCollection z1, ZRowCollection z2)
{
return z1.XRowModified.Select(x => x.Average)
.SequenceEqual(z2.XRowModified.Select(x => x.Average));
}
}
and which would be used like so:
var distinctList = zListCollection.Distinct(CustomComparer.Instance);

Related

Linq query to return object list with multiple child arrays

Incoming list
var list = new List<Franchise>()
{
new Franchise()
{Id = 10, Name = "Franchise1", Code= "DD1", IsDomestic= 1, ParentCompanyId=1, GroupId=100 },
new Franchise()
{Id = 10, Name = "Franchise1", Code= "DD1", IsDomestic= 1, ParentCompanyId=2, GroupId=100 },
new Franchise()
{Id = 10, Name = "Franchise1", Code= "DD1", IsDomestic= 1, ParentCompanyId=3, GroupId=200 },
new Franchise()
{Id = 15, Name = "Franchise5", Code= "FD1", IsDomestic= 0, ParentCompanyId=4, GroupId=300 },
new Franchise()
{Id = 15, Name = "Franchise5", Code= "FD1", IsDomestic= 0, ParentCompanyId=3, GroupId=300 },
new Franchise()
{Id = 15, Name = "Franchise5", Code= "FD1", IsDomestic= 0, ParentCompanyId=2, GroupId=400 },
};
I want this to be transformed to list of the class below using LINQ
public class FranchiseNew
{
public int Id { get; set; }
public string Name{ get; set; }
public int[] CategoryIds { get; set; }
public int[] DivisionIds { get; set; }
public int IsDomestic{ get; set; }
}
output - one row per franchise with ParentCompanyIds and GroupIds in arrays
var list = new List<Franchise>()
{
new Franchise()
{Id = 10, Name = "Franchise1", Code= "DD1", IsDomestic= 1, ParentCompanyIds=[1, 2, 3], GroupIds = [100, 200 ]},
new Franchise()
{Id = 15, Name = "Franchise2", Code= "FD1", IsDomestic= 0, ParentCompanyIds=[4, 3, 2], GroupIds = [300, 400] }
};
What is the efficient LINQ query to achieve this? Thanks in advance.
You can try like below:
var collectionGroup = list.GroupBy(x => new { x.Name, x.Id, x.Code, x.IsDomestic }).ToList();
var result = collectionGroup.Select(x => new FranchiseNew
{
Id = x.Key.Id,
Name = x.Key.Name,
Code = x.Key.Code,
IsDomestic = x.Key.IsDomestic,
CategoryIds = x.GroupBy(s => s.ParentCompanyId).Select(y => y.Key).ToArray(),
DivisionIds = x.GroupBy(s => s.GroupId).Select(y => y.Key).ToArray()
}).ToList();
And in you're FranchiseNew model, add Code field.

Plot Multiple Y-Axis against one X-Axis of DateTime in LiveCharts

In my application, I have four series that I want to plot to a Line Graph. Each series is of the same size, three of which are double and the last one is a DateTime list. The three double series come in a list of class objects of type GraphData which look like this:
public class GraphData
{
public string Name { get; set; }
public List<double> Data { get; set; }
}
As an additional requirement, I want to have a Y-Axis of its own for each of these.
Here's my entire program so far, and it plots the three graphs on its own axes with no problem.
public partial class MainWindow : Window
{
public SeriesCollection SeriesCollection { get; set; }
public AxesCollection YAxesCollection { get; set; }
public List<GraphData> GraphDatas { get; set; }
public List<DateTime> TimeStamps { get; set; }
public MainWindow()
{
InitializeComponent();
GraphDatas = GetGraphData();
TimeStamps = GetTimeStamps(GraphDatas[0].Data.Count);
Plot();
}
private void Plot()
{
SeriesCollection = new SeriesCollection();
YAxesCollection = new AxesCollection();
var count = 0;
foreach (var data in GraphDatas)
{
var gLineSeries = new GLineSeries
{
Title = data.Name,
Values = data.Data.AsGearedValues().WithQuality(Quality.Low),
PointGeometry = null,
Fill = Brushes.Transparent,
ScalesYAt = count
};
SeriesCollection.Add(gLineSeries);
YAxesCollection.Add(new Axis() { Title = data.Name });
count++;
}
DataContext = this;
}
private List<GraphData> GetGraphData()
{
var dataList = new List<GraphData>
{
new GraphData() { Name = "DataA", Data = new List<double>() { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 11.0, 11.0, 9.9, 8.8, 7.7, 6.6, 5.5, 4.4, 3.3, 2.2, 1.1, } },
new GraphData() { Name = "DataB", Data = new List<double>() { 26, 33, 65, 28, 34, 55, 25, 44, 50, 36, 26, 37, 43, 62, 35, 38, 45, 32, 28, 34 } },
new GraphData() { Name = "DataC", Data = new List<double>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 } }
};
return dataList;
}
private List<DateTime> GetTimeStamps(int limit)
{
var timeStamps = new List<DateTime>();
var now = DateTime.Now;
for (int i = 0; i < limit; i++)
{
if (i == 0)
timeStamps.Add(now);
else
{
now = now.AddDays(1);
timeStamps.Add(now);
}
}
return timeStamps;
}
}
My XAML looks simple:
<Grid>
<lvc:CartesianChart Series="{Binding SeriesCollection}"
AxisY="{Binding YAxesCollection}"
DisableAnimations="True"
LegendLocation="Right">
</lvc:CartesianChart>
</Grid>
GetGraphData() and GetTimeStamps() are dummy functions here that simulates my original functions.
Now this works fine, except that the X-axis is not DateTime since obviously I haven't plotted it so. But how would I go about doing this?
The official documentation as well as this SO Post only shows how to do this with only one Y-Axis.
I'd start with some changes to the model in order for it to show the full picture. The timestamp is part of the data point and you'll need to wrap them together to allow the Live Charts mapper to plot the data.
public class DataPoint
{
public DataPoint(DateTime timeStamp, double value)
{
TimeStamp = timeStamp;
Value = value;
}
public double Value { get; }
public DateTime TimeStamp { get; }
}
public class GraphData
{
public string Name { get; set; }
public List<DataPoint> Data { get; set; }
}
If you want to keep the current flow of extraction (CSV), you can simply LINQ Zip the data in to its plottable form.
public partial class MainWindow : Window
{
public SeriesCollection SeriesCollection { get; set; }
public Func<double, string> Formatter { get; set; }
public AxesCollection YAxesCollection { get; set; }
public List<GraphData> GraphDatas { get; set; }
public MainWindow()
{
InitializeComponent();
var timeStamps = GetTimeStamps(20);
GraphDatas = GetGraphData(timeStamps);
Plot();
}
private List<GraphData> GetGraphData(List<DateTime> timeStamps)
{
var valuesA = new List<double>() { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 11.0, 11.0, 9.9, 8.8, 7.7, 6.6, 5.5, 4.4, 3.3, 2.2, 1.1, };
var valuesB = new List<double>() { 26, 33, 65, 28, 34, 55, 25, 44, 50, 36, 26, 37, 43, 62, 35, 38, 45, 32, 28, 34 };
var valuesC = new List<double>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
List<DataPoint> MergeData(List<double> values) => timeStamps.Zip(values, (x, y) => new DataPoint(x, y)).ToList();
var dataList = new List<GraphData>
{
new GraphData() { Name = "DataA", Data = MergeData(valuesA) },
new GraphData() { Name = "DataB", Data = MergeData(valuesB) },
new GraphData() { Name = "DataC", Data = MergeData(valuesC) },
};
return dataList;
}
private void Plot()
{
var mapper = Mappers.Xy<DataPoint>()
.X(dp => (double)dp.TimeStamp.Ticks)
.Y(dp => dp.Value);
SeriesCollection = new SeriesCollection(mapper);
YAxesCollection = new AxesCollection();
var count = 0;
foreach (var data in GraphDatas)
{
var gLineSeries = new GLineSeries
{
Title = data.Name,
Values = data.Data.AsGearedValues().WithQuality(Quality.Low),
PointGeometry = null,
Fill = Brushes.Transparent,
ScalesYAt = count
};
SeriesCollection.Add(gLineSeries);
YAxesCollection.Add(new Axis() { Title = data.Name });
count++;
}
Formatter = value => new DateTime((long)value).ToString("yyyy-MM:dd HH:mm:ss");
DataContext = this;
}
private List<DateTime> GetTimeStamps(int limit)
{
var timeStamps = new List<DateTime>();
var now = DateTime.Now;
for (int i = 0; i < limit; i++)
{
if (i == 0)
timeStamps.Add(now);
else
{
now = now.AddDays(1);
timeStamps.Add(now);
}
}
return timeStamps;
}
}
XAML
<lvc:CartesianChart Series="{Binding SeriesCollection}"
AxisY="{Binding YAxesCollection}"
DisableAnimations="True"
LegendLocation="Right">
<lvc:CartesianChart.AxisX>
<lvc:Axis LabelFormatter="{Binding Formatter}" />
</lvc:CartesianChart.AxisX>
</lvc:CartesianChart>

Group By Multiple Column In LINQ in C#

I have a class like as follows:
public class ActualClass
{
public string BookName { get; set; }
public string IssuerName { get; set; }
public DateTime DateOfIssue { get; set; }
public bool Status { get; set; }
}
It has following data in the table:
I would like to group them by IssuerName and DateOfIssue for the following viewModel class:
public class ViewModel
{
public string IssuerName { get; set; }
public DateTime DateOfIssue { get; set; }
public List<string> Books { get; set; }
}
And data will be displayed as follows: (Screenshot data will be replaced by the previous table data after successful grouping)
Special attention: Is there anything wrong in my ViewModel according to my expectation?
I tried a lot after following some stackoverflow answers but none did work for me. Any help will be highly appreciated.
The code I have tried:
var viewmodel = from b in db.BookIssues
group b by new
{
b.IssuerName,
b.DateOfIssue
}
into g
select new ViewModel()
{
Name = g.key.IssuerName,
DateOfIssue = g.Key.DateOfIssue,
Books = g.ToList() //Actually this line of code is not working
};
Books = g.ToList() //Actually this line of is not working
Probably because Books property is type of List<string>, not List<ActualClass>.
Can you please try this query, I added b.Select(bn => bn.BookName).ToList() to extract only names of books:
var books = new List<ActualClass>
{
new ActualClass { BookName = "A", DateOfIssue = new DateTime(2015, 10, 10, 10, 10, 0), IssuerName = "1" },
new ActualClass { BookName = "B", DateOfIssue = new DateTime(2015, 10, 10, 10, 10, 0), IssuerName = "1" },
new ActualClass { BookName = "C", DateOfIssue = new DateTime(2015, 10, 10, 10, 10, 0), IssuerName = "1" },
new ActualClass { BookName = "D", DateOfIssue = new DateTime(2015, 10, 10, 10, 10, 0), IssuerName = "2" },
new ActualClass { BookName = "E", DateOfIssue = new DateTime(2015, 10, 10, 12, 10, 0), IssuerName = "2" },
new ActualClass { BookName = "F", DateOfIssue = new DateTime(2015, 10, 10, 12, 10, 0), IssuerName = "2" }
};
var result = books.GroupBy(x => new { x.IssuerName, x.DateOfIssue })
.Select(b => new ViewModel
{
Books = b.Select(bn => bn.BookName).ToList(),
// Accessing to DateOfIssue and IssuerName from Key.
DateOfIssue = b.Key.DateOfIssue,
IssuerName = b.Key.IssuerName
});
I grouped by: x.IssuerName, x.DateOfIssue. I did that by passing anonymous type in GroupBy() with following manner: x => new { x.IssuerName, x.DateOfIssue }.
Now they are in key and you can access to IssuerName and DateOfIssue from KEY in SELECT statement like in following: b.Key.IssuerName and b.Key.DateOfIssue.
if you need to select list of books from group result, you need Books = v.Select(c=>c.BookName).ToList() also note that in case of you have time in issue date time you may need to group by only the date part using EntityFunctions.TruncateTime function. if you only storing date only then you can ignore this function.
var viewmodel = db.BookIssues.GroupBy(x=>new {IssuerName =x.IssuerName, DateOfIssue=EntityFunctions.TruncateTime(x.DateOfIssue) })
.Select(v=>new ViewModel(){IssuerName =v.Key.IssuerName, DateOfIssue = v.Key.DateOfIssue, Books = v.Select(c=>c.BookName).ToList() })
.ToList();

Returning jagged array of objects as IEnumerable<IEnumerable<object>>

I'm working on an ASP.NET API and I'm having some issuses retrieving a jagged array of different derived object from a base class.
So I have this Base class:
public class BaseContract
{
public int ID { get; set; }
public enum ContractTypes
{
A,
B
}
public ContractTypes contractType;
public string provider { get; set; }
public string user { get; set; }
public enum OfficeLocations
{
A,
B,
C
}
public OfficeLocations office_location;
public DateTime startDate { get; set; }
public DateTime finishDate { get; set; }
}
And then 4 more classes deriving from this:
public class class1 : BaseContract
{
public enum ProductTypes {
A,
B,
C
}
public ProductTypes productType;
}
And like that i have 4 classes.
Before going into getting the data from the DB i'm filling the classes with some random data manually:
public class ContractsController : ApiController
{
BaseContract[][] contracts = new BaseContract[][]{
new class1[]
{
new class1 {
ID=12412341,
contractType = BaseContract.ContractTypes.A,
productType= Protection_automobile.ProductTypes.B,
startDate= new DateTime(2014, 3, 15),
finishDate= new DateTime(2014, 4, 11),
office_location=BaseContract.OfficeLocations.A,
provider="abc"},
new class1 {
ID=52412341,
contractType = BaseContract.ContractTypes.B,
productType= Protection_automobile.ProductTypes.C,
startDate= new DateTime(2015, 7, 24),
finishDate= new DateTime(2015, 9, 2),
office_location=BaseContract.OfficeLocations.C,
provider="wer"}
},
new class2[]
{
new class2{
ID=22374341,
contractType= BaseContract.ContractTypes.A,
productType = Protection_biens.ProductTypes.B,
startDate = new DateTime(2015,2,2),
finishDate =new DateTime(2015,4,17),
office_location = BaseContract.OfficeLocations.B,
provider= "wer"
},
new class2{
ID=12374659,
contractType = BaseContract.ContractTypes.A,
productType = Protection_biens.ProductTypes.A,
startDate = new DateTime(2015,7,1),
finishDate = new DateTime(2015, 5,30),
office_location = BaseContract.OfficeLocations.A,
provider = "abc"
},
new class2{
ID=12374659,
contractType = BaseContract.ContractTypes.B,
productType = Protection_biens.ProductTypes.A,
startDate = new DateTime(2015,8,2),
finishDate = new DateTime(2015, 5,30),
office_location = BaseContract.OfficeLocations.C,
provider = "abc"
}
},
new class3[]
{
new class3{
ID=32378659,
contractType = BaseContract.ContractTypes.A,
productType = Responsabilite_civile.ProductTypes.A,
startDate = new DateTime(2014,8,2),
finishDate = new DateTime(2015, 1,8),
office_location = BaseContract.OfficeLocations.A,
provider = "abc"
},
new class3{
ID=42395634,
contractType = BaseContract.ContractTypes.A,
productType = Responsabilite_civile.ProductTypes.B,
startDate = new DateTime(2015,7,16),
finishDate = new DateTime(2015, 8,8),
office_location = BaseContract.OfficeLocations.B,
provider = "wer"
},
new class3{
ID=42305635,
contractType = BaseContract.ContractTypes.A,
productType = Responsabilite_civile.ProductTypes.A,
startDate = new DateTime(2015,9,29),
finishDate = new DateTime(2015, 10,6),
office_location = BaseContract.OfficeLocations.B,
provider = "abc"
},
},
new class4[]
{
new class4{
ID=14385634,
contractType = BaseContract.ContractTypes.B,
productType = Protection_persones.ProductTypes.B,
startDate = new DateTime(2015,8,4),
finishDate = new DateTime(2015, 8,9),
office_location = BaseContract.OfficeLocations.A,
provider = "wer"
},
new class4{
ID=14385635,
contractType = BaseContract.ContractTypes.B,
productType = Protection_persones.ProductTypes.B,
startDate = new DateTime(2015,9,11),
finishDate = new DateTime(2015, 9,27),
office_location = BaseContract.OfficeLocations.A,
provider = "abc"
}
}
};
class1[] pContracts = new class1[]{
new class1{
ID=14385634,
contractType = BaseContract.ContractTypes.A,
productType = Protection_persones.ProductTypes.B,
startDate = new DateTime(2015,8,4),
finishDate = new DateTime(2015, 8,9),
office_location = BaseContract.OfficeLocations.A,
provider = "wer"
},
new class1{
ID=14385635,
contractType = BaseContract.ContractTypes.B,
productType = Protection_persones.ProductTypes.A,
startDate = new DateTime(2015,9,11),
finishDate = new DateTime(2015, 9,27),
office_location = BaseContract.OfficeLocations.A,
provider = "abc"
}
};
As you can see, I have a jagged array, and then a simple array.
When i try to get the simple array data as IEnumerable<class1> it works.
But when i try to get the jagged array as IEnumerable<IEnumerable<BaseContract>> it throws an error .
public IEnumerable<class1> GetAllContracts()
{
return pContracts;
}
public IEnumerable<IEnumerable<BaseContract>> getcontracts(){
return contracts;
}
Should I change my jagged array data structure? Or what is the correct wat to retrieve that jagged array?
Thank you.

List<class> how to get subtotal

What would be the simplest way to sum up all the TestScore that are the same SUBJECT and put the total value to each instance?
public class TestScore
{
public int ID { get; set; }
public int SUBJECT { get; set; }
public int SCORE { get; set; }
public int SUBTOTAL { get; set; }
}
List<TestScore> testScores = new List<TestScore>{
new TestScore{ ID = 0, SUBJECT = "MATH", SCORE = 10},
new TestScore{ ID = 1, SUBJECT = "MATH", SCORE = 20},
new TestScore{ ID = 2, SUBJECT = "ENGLISH", SCORE = 10},
new TestScore{ ID = 3, SUBJECT = "ENGLISH", SCORE = 20},
new TestScore{ ID = 4, SUBJECT = "ENGLISH", SCORE = 30},
};
Is there something like?
foreach (TestScore ts in testScores)
{
ts.SUBTOTAL = Sum(testScores.SUBJECT == ts.SUBJECT);
}
Provided that you declare a SUBJECT property in TestScores definition, this is what you need:
var grouped = testScores.GroupBy(ts=>ts.SUBJECT)
.Select(g => new {SUBJECT = g.Key,
Sum = g.Sum(ts=> ts.SCORE)});
The result will be an IEnumerable of an anonymous type, where each instance will have SUBJECT and Sum members.
testScores
.GroupBy(ts => ts.SUBJECT)
.Select(g => new {
Subject = g.Key,
Sum = g.Select(x => x.SCORE).Sum()
})
I think this might be what you are after.
public class TestScore
{
public int ID { get; set; }
public int TYPE { get; set; }
public int SCORE { get; set; }
public string SUBJECT { get; set; }
}
List<TestScore> testScores = new List<TestScore>{
new TestScore{ ID = 0, SUBJECT = "MATH", SCORE = 10},
new TestScore{ ID = 1, SUBJECT = "MATH", SCORE = 20},
new TestScore{ ID = 2, SUBJECT = "ENGLISH", SCORE = 10},
new TestScore{ ID = 3, SUBJECT = "ENGLISH", SCORE = 20},
new TestScore{ ID = 4, SUBJECT = "ENGLISH", SCORE = 30},
};
var tsList = from ts in testScores
group new {ts.SUBJECT,ts.SCORE} by ts.SUBJECT into grp
select new { Subject = grp.Key, Subtotal = grp.Sum(x => x.SCORE) };
foreach(var t in tsList)
Console.WriteLine("Subject: {0} - Subtotal: {1}", t.Subject, t.Subtotal);
Console.WriteLine("Press Any Key to Exit...");
Console.ReadKey();

Categories