Using LINQ, can I verify a property has the same value for all objects?
I have a Crate object, which has a List of KeyValuePairs. Currently, I'm iterating through each pair to see if the kvp.Value.PixelsWide are the same for all items in the List. If they are, return true, else false.
The existi开发者_开发百科ng method that I have is shown below:
public bool Validate(Crate crate)
{
int firstSectionWidth = 0;
foreach (KeyValuePair<string, SectionConfiguration> kvp in crate.Sections)
{
if (firstSectionWidth == 0)//first time in loop
{
firstSectionWidth = kvp.Value.PixelsWide;
}
else //not the first time in loop
{
if (kvp.Value.PixelsWide != firstSectionWidth)
{
return false;
}
}
}
return true;
}
I'm curious if this would be possible to execute in a LINQ query?
Thanks in advance for any help!
I believe this would work:
public bool Validate(Crate crate)
{
return crate.Sections
.Select(x => x.Value.PixelsWide)
.Distinct()
.Count() < 2;
}
This will return true if crate.Sections
is empty as well as when the elements are all the same (which is the behavior of your current function).
Try this
var pixelsWide = rate.Sections.Values.First().PixelsWide;
bool result = crate.Sections.Values.All(x => x.PixelsWide == pixelsWide);
Here's a variation on Stecya's answer that doesn't throw an exception for an empty collection.
var first = crate.Sections.Values.FirstOrDefault();
bool result = crate.Sections.Values.All(x => x.PixelsWide == first.PixelsWide);
If you don't mind iterating through entire collection:
bool hasOneValue = crate.Sections.Select(s => s.Value.PixelsWide).Distinct().Count() == 1;
Or making it consistent with your code:
bool validateResult = crate.Sections.Select(s => s.Value.PixelsWide).Distinct().Count() <= 1;
Is grouping too slow?
public bool Validate(Crate crate)
{
return crate.GroupBy(c => c.Value.PixelsWide).Count() < 2;
}
I'm with @Stecya:
public class Crate
{
IList<KeyValuePair<string,SectionConfiguration>> Sections ;
public bool IsValid()
{
return Sections.All( x => x.Value.PixelsWide == Sections.FirstOrDefault().Value.PixelsWide ) ;
}
public class SectionConfiguration
{
public int PixelsWide ;
}
}
My version:
public bool Validate(Crate crate)
{
return !crate.Sections
.Any(a => crate.Sections
.Where(b => b.Value.PixelsWide != a.Value.PixelsWide).Any()
);
}
This can be implemented as an extension method fairly trivially:
public static bool AllEqual<T1, T2>(this IEnumerable<T1> enumerable, Func<T1, T2> selector)
{
using (var enumerator = enumerable.GetEnumerator())
{
if (!enumerator.MoveNext())
return false;
var first = selector(enumerator.Current);
while (enumerator.MoveNext())
{
var current = selector(enumerator.Current);
if (current == null)
{
if (first == null)
continue;
return false;
}
if (current.Equals(first) == false)
return false;
}
return true;
}
}
My extension method for this looks like this:
public static bool AllAre<T>(this IList<T> self, Func<T, T, bool> predicate)
{
if (self.Count == 0)
{
return true;
}
var first = self.First();
return self.All(arg => predicate(arg, first));
}
And it is used like this:
myList.AllAre((x, first) => x.Value == first.Value);
精彩评论