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();
Related
Here is my previous post.
https://stackoverflow.com/questions/75106799/how-to-get-data-from-3-table-into-1-list/.
It works fine.
But i expect returning value as:
[{ "id": "1f5a6c7c-6168-4ac8-73a5-08daf474a373", "name": "Bag A", "quantity": 10, "category": "Cat-A" }, { "id": "9b8eb0cc-0da4-4b6a-73a6-08daf474a373", "name": "Shirt A", "quantity": 10, "category": "Cat-B" }, { "id": "DB2EE420-A4E5-407A-5F96-08DAF4759F9C", "name": "Shoes A", "quantity": 10, "category": "Cat-C" } ]
I use .net core 6 MVC - code first. Please help me.
I want to return value without "bag", "shirts","shoes". Look like
above:
Well, based on your question, you could achieve by introduing new model which would be containing all property that your "bag", "shirts","shoes" containing. Finally, you need to loop through the existing list item and bind those into new class/model. You can have a try in following way:
Create A new Model for generic List:
public class GenericClass
{
public int Id { get; set; }
public string Name { get; set; }
public int Quantity { get; set; }
public string Category { get; set; }
}
Note: We will use this model to loop over our existing list thus we would bind them into this.
Base Model:
public class GenericClass
{
public int Id { get; set; }
public string Name { get; set; }
public int Quantity { get; set; }
public string Category { get; set; }
}
public class Bags
{
public int Id { get; set; }
public string Name { get; set; }
public int Quantity { get; set; }
public string Category { get; set; }
}
public class Shirts
{
public int Id { get; set; }
public string Name { get; set; }
public int Quantity { get; set; }
public string Category { get; set; }
}
public class Shoes
{
public int Id { get; set; }
public string Name { get; set; }
public int Quantity { get; set; }
public string Category { get; set; }
}
Seed Data Into Model:
List<Bags> listBags = new List<Bags>();
listBags.Add(new Bags() { Id = 101, Name = "Bag A", Quantity = 10, Category = "Cat-A" });
listBags.Add(new Bags() { Id = 102, Name = "Bag B", Quantity = 15, Category = "Cat-A" });
listBags.Add(new Bags() { Id = 103, Name = "Bag C", Quantity = 20, Category = "Cat-A" });
List<Shirts> listShirts = new List<Shirts>();
listShirts.Add(new Shirts() { Id = 101, Name = "Shirt A", Quantity = 10, Category = "Cat-B" });
listShirts.Add(new Shirts() { Id = 102, Name = "Shirt B", Quantity = 15, Category = "Cat-B" });
listShirts.Add(new Shirts() { Id = 103, Name = "Shirt C", Quantity = 20, Category = "Cat-B" });
List<Shoes> listShoes = new List<Shoes>();
listShoes.Add(new Shoes() { Id = 101, Name = "Shirt A", Quantity = 10, Category = "Cat-S" });
listShoes.Add(new Shoes() { Id = 102, Name = "Shirt B", Quantity = 15, Category = "Cat-S" });
listShoes.Add(new Shoes() { Id = 103, Name = "Shirt C", Quantity = 20, Category = "Cat-S" });
Build Custom List:
var genericClass = new List<GenericClass>();
foreach (var item in listBags)
{
var bag = new GenericClass();
bag.Id = item.Id;
bag.Name = item.Name;
bag.Quantity = item.Quantity;
bag.Category = item.Category;
genericClass.Add(bag);
}
foreach (var item in listShirts)
{
var shirt = new GenericClass();
shirt.Id = item.Id;
shirt.Name = item.Name;
shirt.Quantity = item.Quantity;
shirt.Category = item.Category;
genericClass.Add(shirt);
}
foreach (var item in listShoes)
{
var shoes = new GenericClass();
shoes.Id = item.Id;
shoes.Name = item.Name;
shoes.Quantity = item.Quantity;
shoes.Category = item.Category;
genericClass.Add(shoes);
}
Complete Demo:
[HttpGet("GetFrom3TablesWithSameKey")]
public IActionResult GetFrom3TablesWithSameKey()
{
List<Bags> listBags = new List<Bags>();
listBags.Add(new Bags() { Id = 101, Name = "Bag A", Quantity = 10, Category = "Cat-A" });
listBags.Add(new Bags() { Id = 102, Name = "Bag B", Quantity = 15, Category = "Cat-A" });
listBags.Add(new Bags() { Id = 103, Name = "Bag C", Quantity = 20, Category = "Cat-A" });
List<Shirts> listShirts = new List<Shirts>();
listShirts.Add(new Shirts() { Id = 101, Name = "Shirt A", Quantity = 10, Category = "Cat-B" });
listShirts.Add(new Shirts() { Id = 102, Name = "Shirt B", Quantity = 15, Category = "Cat-B" });
listShirts.Add(new Shirts() { Id = 103, Name = "Shirt C", Quantity = 20, Category = "Cat-B" });
List<Shoes> listShoes = new List<Shoes>();
listShoes.Add(new Shoes() { Id = 101, Name = "Shirt A", Quantity = 10, Category = "Cat-S" });
listShoes.Add(new Shoes() { Id = 102, Name = "Shirt B", Quantity = 15, Category = "Cat-S" });
listShoes.Add(new Shoes() { Id = 103, Name = "Shirt C", Quantity = 20, Category = "Cat-S" });
var genericClass = new List<GenericClass>();
foreach (var item in listBags)
{
var bag = new GenericClass();
bag.Id = item.Id;
bag.Name = item.Name;
bag.Quantity = item.Quantity;
bag.Category = item.Category;
genericClass.Add(bag);
}
foreach (var item in listShirts)
{
var shirt = new GenericClass();
shirt.Id = item.Id;
shirt.Name = item.Name;
shirt.Quantity = item.Quantity;
shirt.Category = item.Category;
genericClass.Add(shirt);
}
foreach (var item in listShoes)
{
var shoes = new GenericClass();
shoes.Id = item.Id;
shoes.Name = item.Name;
shoes.Quantity = item.Quantity;
shoes.Category = item.Category;
genericClass.Add(shoes);
}
return Ok(genericClass);
}
Output:
Note: If you still have any concern please have a look on our official documnet here.
I have list say list of customers and inside each list there is another list of orders
Class Customer
{
int ID,
string Name
List<Order> orders
}
Class Order{
int ID,
string Name
}
Also have a integer list of filteredorderIds = {1,2,3,4}
I want to filter the list of customers who has got orderIds from filteredorderIds list.
So far I am stuck at query like
var filteredCustomers = Customers.Where(x => x.Orders.Any(filteredorderIds.contains(y => y.Id)));
please give credit to #Johnathan Barclay, since he posted faster than i typed example
void Main()
{
var customers = new List<Customer>(){
new Customer(){
ID =1,
Name = "Cust1",
orders = new List<Order>(){
new Order(){ID = 4, Name = "o11"},
new Order(){ID = 5, Name = "o12"},
new Order(){ID = 6, Name = "o13"}
}
},
new Customer(){
ID = 2,
Name = "Cust2",
orders = new List<Order>(){
new Order(){ID = 3, Name = "o21"},
new Order(){ID = 7, Name = "o22"},
new Order(){ID = 8, Name = "o23"}
}
}
};
customers.Where(w =>
w.orders.Any(w => filteredorderIds.Contains(w.ID))
).Dump();
}
List<int> filteredorderIds = new List<int>() { 1, 2, 3, 4 };
public class Customer
{
public int ID { get; set; }
public string Name { get; set; }
public List<Order> orders { get; set; }
}
public class Order
{
public int ID { get; set; }
public string Name { get; set; }
}
i am trying to write a linq that will return the id of the employee who has the most entries in the table.
This is how my class looks like
public class TrainingEmployee
{
public int EmployeeId { get; set; }
public int TrainingId { get; set; }
public List<TrainingEmployee> GenerateData()
{
return new List<TrainingEmployee>()
{
new TrainingEmployee() { EmployeeId = 1, TrainingId = 2},
new TrainingEmployee() { EmployeeId = 1, TrainingId = 2},
new TrainingEmployee() { EmployeeId = 1, TrainingId = 2},
new TrainingEmployee() { EmployeeId = 1, TrainingId = 2},
new TrainingEmployee() { EmployeeId = 2, TrainingId = 3},
new TrainingEmployee() { EmployeeId = 2, TrainingId = 3},
new TrainingEmployee() { EmployeeId = 2, TrainingId = 3},
new TrainingEmployee() { EmployeeId = 2, TrainingId = 3},
new TrainingEmployee() { EmployeeId = 2, TrainingId = 5},
new TrainingEmployee() { EmployeeId = 2, TrainingId = 5},
new TrainingEmployee() { EmployeeId = 2, TrainingId = 1},
};
}
}
And this is how my code looks so far
var lista = new TrainingEmployee();
var data = lista.GenerateData().GroupBy(x => x.EmployeeId);
var maxValue = 0;
var employeeId = 0;
foreach (var group in data)
{
var currentlyGroupCount = group.Count();
if(currentlyGroupCount > maxValue)
{
maxValue = currentlyGroupCount;
employeeId = group.Key;
}
}
Console.WriteLine("Value: {0} employeeid: {1}", maxValue, employeeId);
How can i do the above code in just a linq without using that much of a code?
You could order it descending and select the first one:
var employee = GenerateData()
// group on EmployeeId
.GroupBy(e => e.EmployeeId)
// reverse order it on count
.OrderByDescending(g => g.Count())
// select the first
.FirstOrDefault();
// check if the query returned anything other than default.
if(employee != default)
Console.WriteLine("Value: {0} employeeid: {1}", employee.Count(), employee.EmployeeId);
Another approach similar to jeroen-van-langen's answer but using MoreLINQ's MaxBy():
GenerateData()
.GroupBy(e => e.EmployeeId)
.MaxBy(e => e.Count());
This would also return multiple IDs if multiple employee's had the same "max count"; a possibility in your scenario.
This evaluates Count() once for each employees group so is a little more performant, it allows also to get both of employyId and the max count
var mostFrequentEmployeeId = GenerateData()
.GroupBy(x => x.EmployeeId, (employeeId, employeesGroup) => new { employeeId, count = employeesGroup.Count() })
.OrderByDescending(x => x.count)
.FirstOrDefault()?
.employeeId;
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.
How do I need to write to iterate through the results of each of those three initial lists in order to return a single List. Title is the grouping value.
var invoiced = new List<Anonim>
{
new Anonim {Category = 1, Title = "Legal", Amount = 20},
new Anonim {Category = 2, Title = "Accounting", Amount = 10}
}
var settled = new List<Anonim> {
new Anonim {Category = 1, Title = "Legal", Amount = 10}
}
var credit = new List<Anonim> {
new Anonim {Category = 1, Title = "Legal", Amount = 30},
new Anonim {Category = 2, Title = "Accounting", Amount = 20}
}
var result = new List<Result> {
new Result {Title = credit.Title, Invoiced = invoiced.Amount, Settled = settled.Amount, SumAmount = credit.Amount + settled.Amount + invoiced.Amount },
new Result {Title = credit.Title, Invoiced = invoiced.Amount, Settled = settled.Amount, SumAmount = credit.Amount + settled.Amount + invoiced.Amount }
}
public class Result
{
public string Title { get; set; }
public decimal Credit { get; set; }
public decimal Invoiced { get; set; }
public decimal Settled { get; set; }
public decimal SumAmount { get; set; }
}
public class Anonim {
public int Category { get; set; }
public string Title { get; set; }
public decimal Amount { get; set; }
}
SumAmount is the sum of Invoiced, settled, credit of each item
It's a little unclear what you want to happen, but assuming you want to group by the Title property, here's one method. First you project each list into the Result class, making sure to set the relevant properties for each one, union them together into a big list and then group them to get the totals:
var groupedResults = invoiced.Select(i => new Result
{
Title = i.Title,
Invoiced = i.Amount
}).Union(settled.Select(i => new Result
{
Title = i.Title,
Settled = i.Amount
})).Union(credit.Select(i => new Result
{
Title = i.Title,
Credit = i.Amount
}));
var result = groupedResults
.GroupBy(r => r.Title)
.Select(g => new Result
{
Title = g.Key,
Invoiced = g.Sum(r => r.Invoiced),
Settled = g.Sum(r => r.Settled),
Credit = g.Sum(r => r.Credit),
SumAmount = g.Sum(r => r.Invoiced+r.Settled+r.Credit)
});
If I understood you correctly, this is something you want, however this is inefficient due to numerous collection traversals. Maybe #DavidG solution will be more performant.
var groupedSum = invoiced.Union(settled).Union(credit).GroupBy(g => g.Title).Select(g => new Result
{
Title = g.Key,
Credit = credit.Where(c => c.Title == g.Key).Sum(c => c.Amount),
Settled = settled.Where(c => c.Title == g.Key).Sum(c => c.Amount),
Invoiced = invoiced.Where(c => c.Title == g.Key).Sum(c => c.Amount),
SumAmount = g.Sum(i => i.Amount)
});
This is simplest I can find :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication73
{
class Program
{
static void Main(string[] args)
{
List<Anonim> invoiced = new List<Anonim>
{
new Anonim {Category = 1, Title = "Legal", Amount = 20},
new Anonim {Category = 2, Title = "Accounting", Amount = 10}
};
List<Anonim> settled = new List<Anonim> {
new Anonim {Category = 1, Title = "Legal", Amount = 10}
};
List<Anonim> credit = new List<Anonim> {
new Anonim {Category = 1, Title = "Legal", Amount = 30},
new Anonim {Category = 2, Title = "Accounting", Amount = 20}
};
List<Result> results = new List<Result>();
List<string> titles = invoiced.Select(x => x.Title).ToList();
titles.AddRange(settled.Select(x => x.Title).ToList());
titles.AddRange(credit.Select(x => x.Title).ToList();
titles = titles.Distinct().ToList();
foreach(string title in titles)
{
Result newResult = new Result();
results.Add(new Result);
newResult.Title = title;
newResult.Credit = credit.Where(x => x.Title == title).Sum(x => x.Amount);
newResult.Invoiced = invoiced.Where(x => x.Title == title).Sum(x => x.Amount);
newResult.Settled = settled.Where(x => x.Title == title).Sum(x => x.Amount);
newResult.SumAmount = newResult.Credit + newResult.Invoiced + newResult.Settled;
}
}
}
public class Result
{
public string Title { get; set; }
public decimal Credit { get; set; }
public decimal Invoiced { get; set; }
public decimal Settled { get; set; }
public decimal SumAmount { get; set; }
}
public class Anonim
{
public int Category { get; set; }
public string Title { get; set; }
public decimal Amount { get; set; }
}
}
var invoiced = new List<Anonim>
{
new Anonim {Category = 1, Title = "Legal", Amount = 20},
new Anonim {Category = 2, Title = "Accounting", Amount = 10}
};
var settled = new List<Anonim> {
new Anonim {Category = 1, Title = "Legal", Amount = 10}
};
List<Anonim> credit = new List<Anonim> {
new Anonim {Category = 1, Title = "Legal", Amount = 30},
new Anonim {Category = 2, Title = "Accounting", Amount = 20}
};
List<Result> x = new List<Result>();
x.AddRange(invoiced.Select(y => new Result { Title = y.Title, Invoiced = y.Amount }));
x.AddRange(settled.Select(y => new Result { Title = y.Title, Invoiced = y.Amount }));
x.AddRange(credit.Select(y => new Result { Title = y.Title, Invoiced = y.Amount }));
var FinalList = x.GroupBy(a => a.Title).Select(Fn => new Result {
Title =Fn.Key,
Invoiced = Fn.Sum(a => a.Invoiced),``
Settled = Fn.Sum(a => a.Settled),
Credit = Fn.Sum(a => a.Credit),
SumAmount = Fn.Sum(a => a.Invoiced + a.Settled + a.Credit)
});