Convert list of of objects to list of tuple without iterating
Asked Answered
S

4

7

I'm trying to add an extra parameter to a list of ef objects to track processing, but I keep running into having to initialize each list item explicitly. What's the correct linq way to do this? Aside from terseness, is there any advantage to a linq syntax in this case?

List<app_subjects> subjectList = AppMySQLQueries.GetAllSubjects();
List<Tuple<app_subjects, bool>> subjectCollection = new List<Tuple<app_subjects, bool>>(subjectList.Count);

foreach (app_subjects subject in subjectList)
{
     subjectCollection.Add(Tuple.Create(subject, false));
}

I have searched the site without success.

Secor answered 6/9, 2013 at 18:22 Comment(8)
LINQ can do this but it looks very similar to a traditional for or foreach.Glede
LINQ would also do the iteration, (internally)Disposed
@Disposed The difference is that with LINQ you may be able to defer the execution of the work.Toomin
@Servy, true but not when he calls to list which, given the sample code, might be necessary.Mccaskill
@Mccaskill Hence the "may" in my statement.Toomin
@Toomin yeah, I gave some explanation of the deferred execution in my answer.Mccaskill
List<Tuple<T1, T2>> seriously? How about Dictionary<T1, T2>?Cannon
@Dantix you often have no control over what kind of collections you use in a mature code base.Mccaskill
M
18

You just want to use a projection here ( Select ) which applies the transformation in your lambda expression to each element in the source collection.

List<Tuple<app_subjects, bool>> tuples = subjectList.Select(x => new Tuple<app_subjects, bool>(x, false)).ToList();

The ToList() call is not entirely necessary, if you removed it then the method will return an IEnumerable<Tuple<app_subjects, bool>>. If you're just going to iterate the collection of tuples afterwards the ToList call should be removed as it forces execution (enumerates the IEnumerable) and then your next operation (the foreach) would do the same, making the code perform worse.

Mccaskill answered 6/9, 2013 at 18:33 Comment(10)
Sorry, the lambda "x.subject" is invalid because it resolves to a method in the ef class, not the class itself.Secor
@AldoSalzberg yeah, I've put in an edit. I thought app_subject was a property of the objects in the subjectList collection. Since it's actually just a List<app_subject it should be x instead of x.subject.Mccaskill
Use ConvertAll instead.Lx
@It'sNotALie. what is the advantage of using ConvertAll?Mccaskill
@evan It's faster (only enumerates once)Lx
@It'sNotALie. well that's just wrong... If you don't call ToList it enumerates 0 times. And if you call ToList then it enumerates once so it actually performs worse in the one case and the same in the other...Mccaskill
@Mccaskill Oh yeah, I forgot about deffered execution. Fair enough.Lx
I got this error: 'Only parameterless constructors and initializers are supported in LINQ to Entities'Reef
@Reef the tags for this question are misleading. The OP is actually using LINQ to Objects. This part of his code uses EF ist<app_subjects> subjectList = AppMySQLQueries.GetAllSubjects(); but the actual query is not being run by LINQ to Entities, it's LINQ to Objects. When you try it in that context it doesn't work because the LINQ provider translates your query into a SQL query and there are no Tuples in SQL.Mccaskill
@Mccaskill thanks, You right and i found solution for that. please read Yuck answer in this link #17368149Reef
A
8

Like this?

subjectList.Select(s => Tuple.Create(s, false)).ToList();
Agripinaagrippa answered 6/9, 2013 at 18:25 Comment(0)
N
2

With C# 10.0 (.NET 6.0) this is even easier and cleaner. Along with named tuples we can also declare a tuple by simply putting the values in round brackets.

List<(string NamedProperty1, int NamedProperty2)> _tuples = new();
_tuples = _objectList.Select(o => (o.SomeProperty1, o.SomeProperty2)).ToList();
Nigritude answered 1/11, 2022 at 14:36 Comment(0)
S
0

try this.

List<Tuple<app_subjects, bool>> subjectCollection = subjectList.CovertAll( subject => new Tuple<app_subjects, bool>(){
subject,
false
}).ToList();
Stafford answered 6/9, 2013 at 18:30 Comment(1)
Sorry, it has to be Tuple.Create(...), not new Tuple.Secor

© 2022 - 2024 — McMap. All rights reserved.