I have two lists and I want to compare these and update below fields using 2nd list value StudentAddressLine1,StudentAddressLine2,StudentAddressPincode,StudentAddressCity,StudentAddressState
Student Class
public class Student
{
public string StudentNumber { get; set; }
public string StudentName { get; set; }
public string StudentClass { get; set; }
public string StudentPhoneNumber { get; set; }
public string StudentEmail { get; set; }
public string StudentFatherPhoneNumber { get; set; }
public string StudentFatherEmail { get; set; }
public string StudentMotherPhoneNumber { get; set; }
public string StudentMotherEmail { get; set; }
public string StudentAddressLine1 { get; set; }
public string StudentAddressLine2 { get; set; }
public string StudentAddressPincode { get; set; }
public string StudentAddressCity { get; set; }
public string StudentAddressState { get; set; }
public Student SetIndex(int index)
{
RowNo = index;
return this;
}
}
AddressFromExternalAPI Class
public class AddressFromExternalAPI
{
public string SNumber { get; set; }
public string SName { get; set; }
public string SClass { get; set; }
public int ID { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine1 { get; set; }
public string Pincode { get; set; }
public string City { get; set; }
public string State { get; set; }
}
Below is my code where I use a loop and compare two lists and update the fields
public virtual IEnumerable<Student> getStudentDetails(IEnumerable<Student> students)
{
var studentList = new List<Student>();
var addresslist = getStudentAddress(students)
studens.ForEach((y, index ) =>
{
var rowIndex = index 1;
foreach (var address in addresslist)
{
if (rowIndex == address.ID&& y.StudentNumber == address.SNumber &&y.StudentName == address.SName &&y.StudentClass == address.SClass)
{
studentHelper.addAddress(y, ds);
}
studentList.Add(y);
}
});
return studentList;
}
public static void addAddress(Student student, AddressFromExternalAPI address)
{
student.StudentAddressLine1 = address.AddressLine1;
student.StudentAddressLine2 = description.AddressLine2;
student.StudentAddressPincode = description.Pincode;
student.StudentAddressCity = description.City;
student.StudentAddressState = description.State;
}
could you please advise some other way to implement this logic instead of foreach?
Is there any other way instead of doing multiple loops?looking for a more compact solution?
CodePudding user response:
Ignoring ID
, and assuming matching based on Number, Name and Class is sufficient, you can store the addresses in a Dictionary
and lookup the matches:
public virtual IEnumerable<Student> getStudentDetails(IEnumerable<Student> students) {
var addressDict = getStudentAddress(students).ToDictionary(a => (a.SNumber, a.SName, a.SClass));
var studentList = students.ToList();
foreach (var student in studentList) {
if (addressDict.TryGetValue((student.StudentNumber, student.StudentName, student.StudentClass), out var address)) {
student.StudentAddressLine1 = address.AddressLine1;
student.StudentAddressLine2 = address.AddressLine2;
student.StudentAddressPincode = address.Pincode;
student.StudentAddressCity = address.City;
student.StudentAddressState = address.State;
}
}
return studentList;
}
CodePudding user response:
I tried to make it as much as possible with the information given. List<T>.ForEach(Action<T>)
cannot get index.
public static IEnumerable<Student> getStudentDetails(IEnumerable<Student> students)
{
var addressList = getStudentAddress(students);
var result = students
.Select((student, index) => (student, index))
.SelectMany(pair => addressList,
(pair, address) => (pair, address))
.Where(p =>
p.pair.index 1 == p.address.ID &&
p.pair.student.StudentNumber == p.address.SNumber &&
p.pair.student.StudentName == p.address.SName &&
p.pair.student.StudentClass == p.address.SClass)
.Select(p => (p.pair.student, p.address));
var studentList = new List<Student>();
foreach (var (student, address) in result)
{
addAddress(student, address);
studentList.Add(student);
}
return studentList;
}