1

I'm writing out an aggregated list of statuses. It works fine except for the situation where there are none. At the moment, null is rendered and the position is empty.

item.Stuff.Where(e => Condition(e))
  .Select(f => f.Status)
  .Aggregate(String.Empty, (a, b) => a + b)

Now, I'd like to populate the table element with "---" in case the list is filtered down to an empty one by Condition but I can't decide on a method.

What would be a smooth way to approach it?

I've tried something like the atrocity below but it looks, well..., atrociously and it doesn't render right, neither. I get to see the actual source code line (preceded by False or True) instead of the values.

item.Stuff.Where(e => Condition(e)).Count() < 1
  ? "---"
  : item.Stuff.Where(e => Condition(e))
    .Select(f => f.Status)
    .Aggregate(String.Empty, (a, b) => a + b)

2 Answers 2

4

You could do something like this. If the status list is reasonably small (otherwise one should use StringBuilder anyway and not string concatenation).

item.Stuff.Where(e => Condition(e))
    .Select(f => f.Status)
    .Aggregate("---", (a, b) => (a == "---") ? b : (a + b));

It checks if the default text was replaced and, if it was, it concatenates the next status element to the already existing text mass.

This will return "---" if and only if it's never evaluated, i.e. if the list is empty. Otherwise one would get the same result as previously.


If Status is an enum, and you only need the distinct statuses, you can use the behavior of the [Flags] attribute.

If you define the enum like this

[Flags]
enum Status
{
    None = 0,
    Active = 1,
    Inactive = 2,
    Pending = 4,
    Deleted = 8
    ...
}

you can just do:

item.Stuff.Where(e => Condition(e))
  .Aggregate(Status.None, (a, b) => a | b)

The result is a collection of all statuses that are present in the list, and the output is nicely formatted list (Active, Inactive, Pending) or None if it's never run.

Sign up to request clarification or add additional context in comments.

7 Comments

+½ for neatness and +½ for StringBuilder remark. The list is very reasonably small, often only two or three elements, so plus-concat will do fine. The syntax is lengthy as it is already. :)
You could omit the Select and just add b.Status in the Aggregate call to reduce char count :)
I'd give you +1 more if I could. Good point. Sadly, I cheated a bit - Status is an enum so I have to play with ToString and adding that to all the a's and b's would atrocitize the code additionally, I'm afraid. It'd render something like (a.Status.ToString(),b.Status.ToString()), wouldn't it? Nevertheless, a really good remark.
I've added some suggestions how you could handle enums
Really great suggestion - I'll put it in right away, mate. Thanks! I'd bounty you if I wasn't so sneaky on my reputation since they retracted 5000+ score for suspected cheating. :)
|
0

You can use DefaultIfEmpty(string.Empty).First(); MSDN

Example

var item =  item.Stuff.Where(e => Condition(e))
  .Select(f => f.Status)
  .Aggregate(String.Empty, (a, b) => a + b);

var newitem = item.DefaultIfEmpty(new Item() { i = 1, Status = "---" }).First();

1 Comment

I need that on a single line. I'm putting the stuff on a page using Razor.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.