I have a class with the following properties
public class Curve
{
public string CurveName { get; set; }
public string RefSource { get; set; }
public int price1 { get; set; }
public int price2 { get; set; }
public int price3 { get; set; }
public static List<Curve> GetCurveList()
{
List<Curve> data = new List<Curve>()
{
new Curve() { CurveName="Lamar", price1 = 1, price2 = 101,price3=104,RefSource="Tome" },
new Curve() { CurveName="Lamar", price1 = 2, price2 = 201,price3=204,RefSource="Richard" }
}
I need it to get transformed in another list as following properties
curveName=lamar,refSource=richard ,hour=(name of the property of price1, price2,price3)taking integer of the last part of the enclosed property,value associated with the price property
curveName=lamar,refSource=Tom,hour=(name of the property of price1, price2,price3)taking integer of the last part of the enclosed property,value associated with the price property
basically the two items of the source list should result into a new list of 6 rows based on the refsource and each property captioned as price and it need to look like below
Name RefSource Hour Value
lamar tom 1 1
lamar tom 2 101
lamar tom 3 104
lamar richard 1 2
lamar richard 2 201
lamar richard 3 204
The hour column is suffix of property name Price1, price2, price3 in the source list.
Try this:
var query =
from curve in Curve.GetCurveList()
from result in new []
{
new { curve.CurveName, curve.RefSource, Hour = 1, Value = curve.price1 },
new { curve.CurveName, curve.RefSource, Hour = 2, Value = curve.price2 },
new { curve.CurveName, curve.RefSource, Hour = 3, Value = curve.price3 },
}
select result;
That gives me:
Related
Lets say I get the following lines of input in a console application:
A 10 20 30
B 5 10 40
C 40 10 20
D 30 25 10
The letters represent product names, the second value price, the third product score and fourth product endurance. I want to sort this list first off based of price. If two products have the same price then sort based on product score. If two products have the same price and product score, I want to sort on product endurance and finally on names. Would this be possible using merge sort? If so, how should I tackle this problem? I can't store all these values into one array and pass it to the merge sort algorithm, so I'd have to create multiple arrays. But how do I keep track then which values of the arrays belong together? I want to do this in C#.
You can simply use OrderBy and ThenBy on the List of elements. Example below:
void Main()
{
var products = new List<Product>();
products.Add(new Product() { Name = "A", Price = 10, Score = 20, Endurance = 30 });
products.Add(new Product() { Name = "B", Price = 5, Score = 10, Endurance = 40 });
products.Add(new Product() { Name = "C", Price = 40, Score = 10, Endurance = 20 });
products.Add(new Product() { Name = "D", Price = 30, Score = 25, Endurance = 10 });
var resultsSorted = products
.OrderBy(p => p.Price)
.ThenBy(p => p.Score)
.ThenBy(p => p.Endurance)
.ThenBy(p => p.Name);
}
class Product
{
public string Name { get; set; }
public decimal Price { get; set; }
public int Score { get; set; }
public int Endurance { get; set; }
}
[UPDATE]
You did ask how to print those products properly, because Console.WriteLine(product) is not printing "details" of the product. Of course this is because you ended up with default implementation of .ToString() method on objects. You have to either create this string by yourself in foreach loop - or to override .ToString() method so it is either:
foreach(var product in resultsSorted)
{
Console.WriteLine($"Name:{Name}, Price:{Price}, Score:{Score}, Endurance:{Endurance}");
}
or override .ToString
class Product
{
public string Name { get; set; }
public decimal Price { get; set; }
public int Score { get; set; }
public int Endurance { get; set; }
public override string ToString()
{
return $"Name:{Name}, Price:{Price}, Score:{Score}, Endurance:{Endurance}";
}
}
and then you can use:
foreach (var product in resultsSorted)
{
Console.WriteLine(product);
}
In my web application I am fetching 2 lists of objects from database.
First list of objects Employee
1
Name: Tom
Week1: 1
Week2: 3
Week3: 7
2
Name: Mike
Week1: 2
Week2: 1
Week3: 7
Second list of objects listOfId
1
id: 1
color: green
symbol: AT
2
id: 2
color: red
symbol: TB
3
id: 3
color: blue
symbol: TD
I would like to be able now to display it in a form of table, where for each of the weeks, I display this weeks color and symbol (each week matched on Employee.Week# = listOfId.id)
Something like this
Name | Week1 | Week1 Color | Week1 Symbol | Week2 | Week 2 Color etc...
Tom 1 green AT 3 blue
Mike 2 red TB 1 green
In total I will have constant 20 weeks for each employee.
I considered writing a SQL query which would take in week id, and return color and symbol. But for 50 people * 20 weeks... I would need to run this query 1000 times.
I am looking for better approach to solving this issue
my Models:
public class WeekViewModel
{
public int Id{ get; set; }
public string ShortNAme { get; set; }
public string Description { get; set; }
public int Color { get; set; }
}
}
public class EmployeeWeekViewModel
{
public string full_name { get; set; }
public string location { get; set; }
public int week1 { get; set; }
public int week2 { get; set; }
public int week3 { get; set; }
}
If I'm getting your correct, you have two lists coming from DB:
employeesList which represents the employees with their corresponding weeks ID
weeksList which represents the weeks for an employee.
Now, you want to join these two lists to display the information in a simple table format. I would do something like that:
public class EmployeeWeekViewModel{
public string EmployeeName{get;set;}
public WeekViewModel Week1 {get;set;}
public WeekViewModel Week2 {get;set;}
...
public WeekViewModel Week20 {get;set;}
}
public class WeekViewModel{
public int Id{get;set;}
public string Color{get;set;}
public string Symbol{get;set;}
}
employeesList.Select(t=> new EmployeeWeekViewModel(){
EmployeeName = t.Name,
Week1 = weeksList.FirstOrDefault(w => w.id == t.Week1).Select(w => new WeekViewModel(){
Id = w.id,
Color = w.color,
Symbol = w.symbol
}),
Week2 = weeksList.FirstOrDefault(w => w.id == t.Week2).Select(w => new WeekViewModel(){
Id = w.id,
Color = w.color,
Symbol = w.symbol
}),
...
});
In order to not make a request for each week, I would suggest send to you query a list of week Ids to get them once (checkout this example).
I have a list that contains about 50 properties of a class. What I'm struggling with is I"m trying to take a count of the distinct values of two properties This "count" number then needs to be added on to the end of the list of each group by.
For example: here is my class
public class ListType
{
public ListType()
{
}
public string ID { get; set; }
public string REGSID { get; set; }
public string county { get; set; }
public string act_loc { get; set; }
public string eviofnd { get; set; }
public string hmonth { get; set; }
public string hisnc { get; set; }
public string hinc { get; set; }
public string FIPS { get; set; }
public decimal back00 {get; set;}
public decimal ann00 { get; set; }
public int countDistinctID {get;set;}
}
I need to take a count of distinct IDS of each distinct FIPS and then that count of the distinct IDS is set to countDistinctID property of each grouped FIPS.
ID FIPS other columns(still need this data though)
4 1 ......
5 2 ....
4 1 ....
4 2 ....
1 3 .....
1 2 ....
2 1 .....
What I need is this...
ID FIPS other columns count
4 1 ...... 2 3 rows with FIPS =1 then 2 distinct ID's per FIPs=1
5 2 .... 3 3 rows w/FIPS=2 3 distinct IDS per FIps=2
4 1 .... 2
4 2 .... 3
1 3 ..... 1 1 row w/fips=3 1 distinct id perFIPS=3
1 2 .... 3
2 1 ..... 2
I've parsed in a file and I write all the columns to a list called List data
what I ultimately need to do after I take count of distinct ID's is then set that count value to countDistinctID of the original "data" list and do that for each distinct FIPS and ID per that distinct FIPS
census.countDistinctID
Try this
var distinct = censu.Select(a => a.Select(x=>x.ID).Distinct().Count());
var censu = data.GroupBy(a => a.FIPS).ToList();
foreach (var grp in censu)
{
var count = grp.Select(p=>p.ID).Distinct().Count();
foreach (var d in grp)
d.countDistinctID = count;
}
My question is similar too THIS
I have two DataTables:
DataTable 1:
Column 1: Date
Column 2: Requests 1
DataTable 2:
Column 1: Date
Column 2: Requests 2
I need the bellow result:
New DataTable:
Column 1: Date
Column 2: Requests 1
Column 3: Requests 2
Expected Result:
Date Requests 1 Requests 2 Total
15/08/2013 25 40 60
14/08/2013 40 60 100
13/08/2013 40 0 25
12/08/2013 0 80 80
What I did until now:
DataTable Lista_1 = ds.Tables[0];
DataTable Lista_2 = ds.Tables[1];
var myLINQ = from l1 in Lista_1.AsEnumerable()
join l2 in Lista_2.AsEnumerable()
on l1.Field<DateTime>("Date") equals l2.Field<DateTime>("Date")
select new
{
dateRelatorio = l1.Field<DateTime>("Date"),
request1Relatorio = l1.Field<int>("Total"),
request2Relatorio = l2.Field<int>("contagem"),
total = l1.Field<int>("Total") + l2.Field<int>("contagem")
};
And I would like to return an IList collection (System.Collections.IList)
UPDATE
listReturn = new List<Stats>();
public class Stats
{
public DateTime dateRelatorio { get; set; }
public int request1Relatorio { get; set; }
public int request2Relatorio { get; set; }
public int total { get; set; }
}
UPDATE 2
May have dates in List_1 that there is not in List_2 and vice versa, so the Request need to be 0.
If you need this thing to be encapsulated in a method, you should create a class to be returned:
public class DailyReport
{
public DateTime Date {get; set;}
public int Requests1 {get; set;}
public int Requests2 {get; set;}
public int Total // this can be calculated on the fly
{
get {return Requests1 + Requests2; }
}
}
And then do
public List<DailyReport> GetDailyReports(..parameters if needed...)
{
...
var myLINQ = from ...
select new DailyReport {
Date = l1.Field<DateTime>("Date"),
Requests1 = l1.Field<int>("Total"),
Requests2 = l2.Field<int>("contagem"),
};
return myLINQ.ToList();
}
There are some dirty hacks that could enable you to return an collection of anonymous objects, but I would advise against it.
Consider i have a datatable retrieved from oracle database in the following format
SNo. | Product | Cost
-------------------------------------------------
1 | colgate,closeup,pepsodent | 50
2 | rin,surf | 100
I need to change this into the following format using linq.Need to separate the product column with the help of comma by keeping the other columns same.
SNo. | Product | Cost
-------------------------------------
1 | colgate | 50
1 | closeup | 50
1 | pepsodent | 50
2 | rin | 100
2 | surf | 100
Please try this:
List<Product> uncompressedList = compressedProducts
.SelectMany(singleProduct => singleProduct.ProductName
.Split(',')
.Select(singleProductName => new Product
{
SNo = singleProduct.SNo,
ProductName = singleProductName,
Cost = singleProduct.Cost
}))
.ToList();
EDIT:
Product class is defined as follows:
public class Product
{
public Int32 SNo { get; set; }
public String ProductName { get; set; }
public Int32 Cost { get; set; }
}
and compressedProducts is just the initial list of products from your first example.
I know that this is not a single-line Linq statement but, try this.
var output = new List<Product>();
foreach (var p in SqlResult)
{
var products = p.Product.Split(',');
output.AddRange(products.Select(product => new Product { SNo = p.SNo, ProductName = product, Cost = p.Cost }));
}
By-the-way, SqlResult is your results set from the database.
This appears to work from my limited testing...
var test = p1.Product.Split(',').Select(p => new { product = p }).Select(r => new { p1.SNo, r.product, p1.Cost, })
This is only for a single line, but can easily be explanded to include mutiple lines....
I would favour a simple foreach because it is known than LINQ is slower that regular looping statements, but if you really want to go that path you could use something like which to you, maybe be easier to read:
Given
class ProductOracle
{
public int SNo { get; set; }
public string Product { get; set; }
public decimal Cost { get; set; }
}
class ProductEntity
{
public int SNo { get; set; }
public string Product { get; set; }
public decimal Cost { get; set; }
}
Execution
var entities = new List<ProductOracle>
{
new ProductOracle{SNo=1,Product="colgate,closeup,pepsodent", Cost=50},
new ProductOracle{SNo=2,Product="rin,surf", Cost=100}
};
With
var products = new List<ProductEntity>();
entities.ForEach(element =>
{
element.Product.Split(',').ToList().ForEach(product =>
{
products.Add(new ProductEntity { SNo = element.SNo, Product = product, Cost = element.Cost });
});
});
Or
var products = entities.SelectMany(element =>
{
var ProductEntities = new List<ProductEntity>();
element.Product.Split(',').ToList().ForEach(product =>
{
ProductEntities.Add(new ProductEntity { SNo = element.SNo, Product = product, Cost = element.Cost });
});
return ProductEntities;
});