I have a variable:
public static List<CardSetWithWordCount> cardSetWithWordCounts;
Where the class looks like this;
public class CardSetWithWordCount
{
public int Id { get; set; }
public string Name { get; set; }
public bool IsToggled { get; set; }
public int TotalWordCount { get; set; }
}
How can I check if:
I was thinking about LINQ as I have used this before but I am not sure this level of checking is possible with LINQ. I am interested to see if anyone knows if it's possible or will I just need to code a forEach loop or some other construct. Any tips would be much appreciated.
This is a slightly more efficient version of felix-b's answer - it doesn't require creating a new list. It will return as soon as it's sure of the result, without any need for checking the rest of the elements.
string GetDescription(IEnumerable<CardSetWithWordCount> cardSets)
{
CardSetWithWordCount firstMatch = null;
foreach (var match in cardSets.Where(x => x.IsToggled))
{
if (firstMatch != null)
{
// We've seen one element before, so this is the second one.
return "mixed";
}
firstMatch = match;
}
// We get here if there are fewer than two matches. The variable
// value will be null if we haven't seen any matches, or the first
// match if there was exactly one match. Use the null conditional
// operator to handle both easily.
return firstMatch?.Name;
}
For a more purely LINQ version, I'd use felix-b's answer
To explore other pure LINQ alternatives that don't need to materialize results, you could use Aggregate
.
First, a version that relies on Name
being non-null:
static string GetDescription(IEnumerable<CardSetWithWordCount> cardSets) =>
cardSets
.Where(x => x.IsToggled)
.Take(2)
.Select(match => match.Name)
.Aggregate<string, string>(
null, // Seed
(prev, next) => prev == null ? next : "mixed");
An alternative that doesn't rely on Name
being non-null, but does create a new object if the result is going to be "mixed":
static string GetDescription(IEnumerable<CardSetWithWordCount> cardSets) =>
cardSets
.Where(x => x.IsToggled)
.Take(2)
.Aggregate(
(CardSetWithWordCount) null, // Seed
(prev, next) => prev == null
? next : new CardSetWithWordCount { Name = "mixed" })
?.Name;
All of these ensure that they only evaluate the input once, and stop as soon as the result is known.
See more on this question at Stackoverflow