Reputation: 14682
I'm having two list like
List<String> l_lstNames = new List<String> { "A1", "A3", "A2", "A4", "A0" };
List<Test> l_lstStudents = new List<Test>
{ new Test { Age = 20, Name = "A0" },
new Test { Age = 21, Name = "A1" },
new Test { Age = 22, Name = "A2" },
new Test { Age = 23, Name = "A3" },
new Test { Age = 24, Name = "A4" },
};
Where Test
is class like
public class Test
{
public String Name;
public Int32 Age;
}
I need to sort the items in the l_lstStudents
based on the l_lstNames
. So the sorted list will be like,
List<Test> l_lstStudents = new List<Test>
{ new Test { Age = 21, Name = "A1" },
new Test { Age = 23, Name = "A3" },
new Test { Age = 22, Name = "A2" },
new Test { Age = 24, Name = "A4" },
new Test { Age = 20, Name = "A0" },
};
Now i'm using for
to do this.
Like
Create a new list of Test
objects.
Iterate the loop for l_lstNames
and fetch the Test
object from l_lstStudent
and add the same to the newly created list. Finally assign the new list to l_lstStudent
Please help me to do this in a simple way ( Linq or Lambda)
Upvotes: 9
Views: 3250
Reputation: 18137
var newList = l_lstNames.Join(l_lstStudents,
s => s,
test => test.Name,
(s, test) => new Test { Name = s, Age = test.Age }
).ToList();
Upvotes: 1
Reputation: 12348
Using
l_lstStudents = l_lstStudents.OrderBy(x => l_lstNames.IndexOf(x.Name)).ToList();
in a small test program
public class Test
{
public String Name;
public Int32 Age;
}
class Program
{
static void Main(string[] args)
{
List<String> l_lstNames = new List<String> { "A1", "A3", "A2", "A4", "A0" };
List<Test> l_lstStudents = new List<Test>
{ new Test { Age = 20, Name = "A0" },
new Test { Age = 21, Name = "A1" },
new Test { Age = 22, Name = "A2" },
new Test { Age = 23, Name = "A3" },
new Test { Age = 24, Name = "A4" },
};
l_lstStudents = l_lstStudents.OrderBy(x => l_lstNames.IndexOf(x.Name)).ToList();
}
}
results in
Age 21 int
Name "A1" string
Age 23 int
Name "A3" string
Age 22 int
Name "A2" string
Age 24 int
Name "A4" string
Age 20 int
Name "A0" string
and thus is:
List<Test> l_lstStudents = new List<Test>
{ new Test { Age = 21, Name = "A1" },
new Test { Age = 23, Name = "A3" },
new Test { Age = 22, Name = "A2" },
new Test { Age = 24, Name = "A4" },
new Test { Age = 20, Name = "A0" },
};
Upvotes: 1
Reputation: 111860
Try something like:
List<String> l_lstNames = new List<String> { "A1", "A3", "A2", "A4", "A0" };
List<Test> l_lstStudents = new List<Test>
{ new Test { Age = 20, Name = "A0" },
new Test { Age = 21, Name = "A1" },
new Test { Age = 22, Name = "A2" },
new Test { Age = 23, Name = "A3" },
new Test { Age = 24, Name = "A4" },
};
// We transform the list in a dictionary to make it faster to access.
// The first Select creates a new object with the index of the name and
// the ToDictionary creates the Dictionary.
// Note that technically on a small list (like 5 elements)
// it's probably faster to IndexOf directly the List...
// This is the problem of premature optimization :-) :-)
// If you know the list will always be 5 elements then probably
// IndexOf is more than enough.
var dict = l_lstNames.Select((p, i) => new { Index = i, Name = p })
.ToDictionary(p => p.Name, p => p.Index);
// We sort it. This works because 3 < 5 => 3 - 5 < 0, 5 > 3 => 5 - 3 > 0, 5 == 5 => 5 - 5 == 0
l_lstStudents.Sort((p, q) => dict[p.Name] - dict[q.Name]);
// We could do something like and it would be clearer.
l_lstStudents.Sort((p, q) => dict[p.Name].CompareTo(dict[q.Name]));
Upvotes: 1
Reputation:
Try out with following code:
l_lstStudents = (from name in l_lstNames
join student in l_lstStudents
on name equals student.Name
select student).ToList<Test>();
Upvotes: 1
Reputation: 5444
Try this. Putting it in a dictionary may save some look up time:
int i = 0;
Dictionary<string, int> ordinalValues = l_lstNames.ToDictionary(name => name, name => i++);
var sortedStudents = l_lstStudents.OrderBy( a => ordinalValues[a.Name]).ToList();
Upvotes: 1
Reputation: 39610
Try this:
l_lstStudents = l_lstStudents.OrderBy(s => l_lstNames.IndexOf(s.Name)).ToList()
I think that expresses the intention quite clearly.
Upvotes: 9
Reputation: 50114
How about
var studentLookup = l_lstStudents.ToDictionary(s => s.Name, s => s);
return l_lstNames.Select(n => studentLookup[n]);
Upvotes: 2