patterncsharpModerate
Using LINQ or Lambda instead of nested and multiple foreach statements
Viewed 0 times
linqstatementsforeachinsteadnestedusingmultipleandlambda
Problem
I want to use a better syntax than nested
In the code below:
New
foreach statements to overwrite the initial list with items from the second list.In the code below:
- I want to overwrite
initialListwith those insecondListthat have the sameValue(Remove Red).
- Use the items in
secondListwhereValuewas the same (Yellow)
New
initialList list should include (Green and Yellow).static void Main(string[] args)
{
int useProd = 2;
int useDomain = 0;
var person1 = new Person() { prodId = 1, Value = "foo", domainId = 0, Name = "Red" };
var person2 = new Person() { prodId = 1, Value = "bar", domainId = 0, Name = "Green" };
var person3 = new Person() { prodId = 1, Value = "foo", domainId = 1, Name = "Yellow" };
var initialList = new List();
initialList.Add(person1);
initialList.Add(person2);
var secondList = new List();
secondList.Add(person3);
List personsToRemove = new List();
List personsToUpdate = new List();
foreach (var pers1 in initialList)
{
foreach (var pers2 in secondList)
{
if (pers1.Value == pers2.Value)
{
personsToRemove.Add(pers1);
personsToUpdate.Add(pers2);
}
}
}
foreach (var remPers in personsToRemove)
{
initialList.Remove(remPers);
}
foreach (var updPers in personsToUpdate)
{
initialList.Add(updPers);
}
foreach (var item in initialList)
{
Console.WriteLine(String.Format("Value: {0}, prodId: {1}, domainId: {2}, Name: {3}", item.Value, item.prodId, item.domainId, item.Name));
}
Console.ReadKey();
}
public class Person
{
public int prodId { get; set; }
public string Value { get; set; }
public int domainId { get; set; }
public string Name { get; set; }
}Solution
By using an
you can by using linq methods replace the loops by
We are first using the
You should always use meaningful and descriptive names for naming methods, variables, properties and classes so Sam the Maintainer sees at first glance what it is about.
Shortening variable names doesn't add any value but instead reduces readability which Sam the Maintainer doesn't like.
IEqualityComparer which only compares the Value property like public class PersonValueComparer : IEqualityComparer
{
public bool Equals(Person x, Person y)
{
if (x == null && y == null) { return true; }
if (x == null || y == null) { return false; }
return x.Value == y.Value;
}
public int GetHashCode(Person obj)
{
if (obj == null || obj.Value == null) {return 0;}
return obj.Value.GetHashCode();
}
}you can by using linq methods replace the loops by
PersonValueComparer valueComparer = new PersonValueComparer();
initialList = secondList.Where(p => initialList.Contains(p, valueComparer))
.Concat(initialList.Where(p => !secondList.Contains(p, valueComparer))).ToList();We are first using the
Where() method to filter the secondList for items which are in the initialList . Then we use Concat() to add the Person''s which are not in thesecondList.
Based on the naming guidelines properties should be named using PascalCase` casing. You should always use meaningful and descriptive names for naming methods, variables, properties and classes so Sam the Maintainer sees at first glance what it is about.
Shortening variable names doesn't add any value but instead reduces readability which Sam the Maintainer doesn't like.
Code Snippets
public class PersonValueComparer : IEqualityComparer<Person>
{
public bool Equals(Person x, Person y)
{
if (x == null && y == null) { return true; }
if (x == null || y == null) { return false; }
return x.Value == y.Value;
}
public int GetHashCode(Person obj)
{
if (obj == null || obj.Value == null) {return 0;}
return obj.Value.GetHashCode();
}
}PersonValueComparer valueComparer = new PersonValueComparer();
initialList = secondList.Where(p => initialList.Contains(p, valueComparer))
.Concat(initialList.Where(p => !secondList.Contains(p, valueComparer))).ToList();Context
StackExchange Code Review Q#80175, answer score: 11
Revisions (0)
No revisions yet.