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)
Try this:
l_lstStudents = l_lstStudents.OrderBy(s => l_lstNames.IndexOf(s.Name)).ToList()
I think that expresses the intention quite clearly.
How about
var studentLookup = l_lstStudents.ToDictionary(s => s.Name, s => s);
return l_lstNames.Select(n => studentLookup[n]);
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]));
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" },
};
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();
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>();
var newList = l_lstNames.Join(l_lstStudents,
s => s,
test => test.Name,
(s, test) => new Test { Name = s, Age = test.Age }
).ToList();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.