C# LINQ Combine values of 2 lists [closed] - c#

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I have a list with tickets in it:
TicketID - Aantal (amount) - ActiePrijs (price)
For all those tickets the ActiePrijs (price) is still empty. But I also have a list with only those Actieprijs (prices). It's just a list of decimals.
Now I want to put the first actiePrijs from the decimal list into the ActiePrijs from the first ticket, the second ActiePrijs into the ActiePrijs of the second ticket etc.
I want to do it using linq method syntax.
Can someone help me?

I assume tickets & price lists are tickets and price.
You can use linq like below.
tickets = tickets.Select((ticket, index) => new Ticket
{
TicketID = ticket.TicketID,
Aantal = ticket.Aantal,
ActiePrijs = price[index]
})
.ToList();
Or if you have more properties and you do not want to create new object then use like below.
tickets = tickets.Select((ticket, index) =>
{
ticket.ActiePrijs = price[index];
return ticket;
})
.ToList();

You dont show any code, but I thing you want something like this.
public class Properties
{
public int Aantal { get; set; }
public int Price { get; set; }
}
List<Properties> l = new List<Properties>();
l.Add(new Properties() { Aantal = 1 });
l.Add(new Properties() { Aantal = 2 });
l.Add(new Properties() { Aantal = 3 });
List<int> l2 = new List<int>();
l2.Add(1);
l2.Add(2);
l2.Add(3);
int index = 0;
l.ForEach(x => x.Price = l2[index++]);

Related

C# Join string from object with LINQ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last month.
Improve this question
I currently have an object that I have defined like this.
public class Model {
public string id {get; set;}
public string customer {get; set;}
public string sentence {get; set;}
}
When working with my object I do it in collections which can have repeated elements by id and customer but different sentence, I need to iterate the common elements and join it's sentence like so:
id
customer
sentence
1
001
why
1
001
that
2
002
seperate
I am trying to convert this to the following:
id
customer
sentence
1
001
why, that
2
002
seperate
I currently have this code:
List<Model> data = JsonConvert.DeserializeObject<List<Model>>(json);
List<Model> result = data.GroupBy(x => new {
x.id,
x.customer
}).Select(x => new Model {
id = x.Key.id,
customer = x.Key.customer,
sentence = String.Join(", ", x.Select(z => z.sentence)) // this is what I need to fix
}).ToList();
This however doesn't seem to work, what can I do to fix this. Can anyone help me with this? Thanks in advance.
EDIT:
The tables shown are the visual representation of a List, the first one would be the data variable and the last one how I want the result variable to be. The code doesn't work, it will still return the first visual representation.
My apologies for the unclear question.
There's a code typo, the following works as you need:
List<Model> data = JsonConvert.DeserializeObject<List<Model>>(json);
List<Model> result = data.GroupBy(x => new {
x.id,
x.customer
}).Select(x => new Model {
id = x.Key.id,
customer = x.Key.customer,
sentence = string.Join(", ", x.Select(z => z.sentence))
}).ToList();
Output:
1|001|why, that
2|002|seperate

How to use linq to split a list of objects by half and then group them [duplicate]

This question already has answers here:
Split List into Sublists with LINQ
(34 answers)
Closed 3 years ago.
I have a list of n objects (17 for now) and I wanted to know if it is possible to take said list and split it into (potentially) 2 groups. That way the end result would be
NewList
-"GroupA"
-List1 = {"john", "mary", "sam"}
-"GroupB"
-List2 = {"tony", "aaron"}
The desired result would help me output the first half of the list of students in page 1 and then using paging the user can then view the remaining list on the next page.
Right now I am trying to do something like this:
var groupList = Classroom.GroupBy(o => o).Select(grp=>grp.Take((Classroom.Count + 1) / 2)).ToList();
But when I debug it I'm still getting the full list. Can it be done via linq?
You can create group by some property. For example, we have 50 students, then we can make GroupId property and group them by GroupId property:
var students = new List<Student>();
for (int i = 0; i < 50; i++)
{
students.Add(new Student { Id = i, Name = $"Student { i }" });
}
var sectionedStudents = students.Select(s => new
{
GroudId = s.Id / 10,
s.Id,
s.Name
});
var groupedStudents = sectionedStudents.GroupBy(s => s.GroudId);
and Person class:
class Student
{
public int Id { get; set; }
public string Name { get; set; }
}

Random with condition

I have the following code to extract records from a dbcontext randomly using Guid class:
var CategoryList = {1,5};
var generatedQues = new List<Question>();
//Algorithm 1 :)
if (ColNum > 0)
{
generatedQues = db.Questions
.Where(q => CategoryList.Contains(q.CategoryId))
.OrderBy(q => Guid.NewGuid()).Take(ColNum).ToList();
}
First, I have a list of CategoryId stored in CategoryList as a condition to be fulfilled when getting records from the db. However, I would like to achieve an even distribution among the questions based on the CategoryId.
For example:
If the ColNum is 10, and the CategoryId obtained are {1,5}, I would like to achieve by getting 5 records that are from CategoryId = 1 and another set of 5 records from CategoryId = 5. If the ColNum is an odd number like 11, I would also like to achieve an even distribution as much as possible like maybe getting 5 records from CategoryId 1 and 6 records from CategoryId 2.
How do I do this?
This is a two step process,
Determine how many you want for each category
Select that many items from each category in a random order
For the first part, define a class to represent the category and how many items are required
public class CategoryLookup
{
public CategoryLookup(int catId)
{
this.CategoryId = catId;
}
public int CategoryId
{
get; private set;
}
public int RequiredAmount
{
get; private set;
}
public void Increment()
{
this.RequiredAmount++;
}
}
And then, given your inputs of the required categories and the total number of items required, work out how many are required for each category
var categoryList = new []{1,5};
var colNum = 7;
var categoryLookup = categoryList.Select(x => new CategoryLookup(x)).ToArray();
for(var i = 0;i<colNum;i++){
categoryLookup[i%categoryList.Length].Increment();
}
The second part is really easy, just use a SelectMany to get the list of questions (Ive used a straight linq to objects to test, should work fine for database query. questions in my code would just be db.Questions in yours)
var result = categoryLookup.SelectMany(
c => questions.Where(q => q.CategoryId == c.CategoryId)
.OrderBy(x => Guid.NewGuid())
.Take(c.RequiredAmount)
);
Live example: http://rextester.com/RHF33878
You could try something like this:
var CategoryList = {1,5};
var generatedQues = new List<Question>();
//Algorithm 1 :)
if (ColNum > 0 && CategoryList.Count > 0)
{
var take = // Calculate how many of each
// First category
var query = db.Questions
.Where(q => q.CategoryId == CategoryList[0])
.OrderBy(q => Guid.NewGuid()).Take(take);
// For all remaining categories
for(int i = 1; i < CategoryList.Count; i++)
{
// Calculate how many you want
take = // Calculate how many of each
// Union the questions for that category to query
query = query.Union(
query
.Where(q => q.CategoryId == CategoryList[i])
.OrderBy(q => Guid.NewGuid()).Take(take));
}
// Randomize again and execute query
generatedQues = query.OrderBy(q => Guid.NewGuid()).ToList()
}
The idea is to just get a random list for each category and add them all together. Then you randomize that again and create your list. I do not know if it will do all this on the database or in memory, but it should be database I think. The resulting SQL will look horrible though.

C# linq group By on field and result string? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
how to write dynamic groupby with selectfieldString and resultFieldString?
sample:
public class Customer
{
public int Id;
public string Name;
public string LastName;
public decimal Amount;
}
var lst = new List<Customer>();
lst.Add(new Customer { Id = 1, Name = "vahid", LastName = "Aghilpour", Amount = 15 });
lst.Add(new Customer { Id = 1, Name = "hamid", LastName = "rezaei", Amount = 35 });
lst.Add(new Customer { Id = 1, Name = "vahid", LastName = "Aghilpour", Amount = 15 });
string[] field = { "Name", "LastName" };
string aggrigatefield = "Sum(Amount)";
lst.GroupBy(field).Select(aggrigatefield);---??????????
By using dynamic linq you should be able to do it.
// Remember: using System.Linq.Dynamic;
// The format for the key of the GroupBy is "new(field1,field2)"
// "it" as elementSelector means "the full object"
string field = string.Format("new({0})", string.Join(",", fields));
decimal[] res = lst.GroupBy(field, "it")
.Select(aggrigatefield)
.Cast<decimal>()
.ToArray();
Note that if the Select is totally dynamic (so it could return a Sum(), or a string field, or a decimal field, or a complex object or a ???), then you can't really do a Cast<decimal>(), because you "statically" don't know the type of the returned object. You have to do
object[] res = lst.GroupBy(field, "it")
.Select(aggrigatefield)
.Cast<object>()
.ToArray();
or
dynamic[] res = lst.GroupBy(field, "it")
.Select(aggrigatefield)
.Cast<dynamic>()
.ToArray();

dynamic list in C# [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
if(some condition)
{
var columnSeries = (from l in logs
group l by l.MonitoringPorfileName into grp
select new
{
type = "column",
name = grp.Key,
data = (from h in Hours
let gd = grp.Where(x => x.Hours == h)
select gd.Sum(x => x.Count)).ToArray()
}).ToList();
}
}
How can i make this variable columnSeries a global variable? i have searched a lot on this, found list dynamic> new{}; but none of them are working so help will be really appreciated
Make the anonymous type you want a class.
public class ColumnSeries
{
public string type {get; set;}
//...
}
//class level variable
IEnumerable<ColumnSeries> columnSeries = null;
//then create the ColumnSeries list
columnSeries = (from l in logs
group l by l.MonitoringPorfileName into grp
select new ColumnSeries
{
type = "column",
name = grp.Key,
data = (from h in Hours
let gd = grp.Where(x => x.Hours == h)
select gd.Sum(x => x.Count)).ToArray()
});
You are creating an anonymous type inside your if statment but you want to use the result ouside the scope of the if statement. Usually you just define 'columnSeries' before the if BUT this is an anonymous type so it's not obvous.
So, before the if statement do the following (untested but should be close):
var columnSeries = Enumerable.Repeat(new {type="", name="", data=new int[]{0}}, 0);
Check out this question for more info

Categories

Resources