Listing a field from all the entities in a collect

2019-08-05 09:13发布

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("---", (a, b) => (a == "---") ? b : (a + b));

I've got a suggestion for solution and improvement as follows.

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

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

As I'm a great fan of simpler syntax, I love skipping the Select part. However, the result now is not all the elements listed. In fact, only a single one is listed (instead of five as previously) and None appears where there was a single status before.

Perhaps I'm too brain-stuck but I can't see why. And, consequently, not what I should do about it, neither... :(

1条回答
干净又极端
2楼-- · 2019-08-05 09:46

If the statuses are coming from an extenal system (i.e. a database) you might need to renumber the statuses there as well.

Note that this works only if you use power-of-two values as the values of the statuses.

Eg. if I use

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

then Status.Active | Status.Inactive will return Status.Pending (1+2=3).

Also, this way you only get a list of distinct used statuses, i.e. if you have 10 active and 5 pending items, you'll get Active, Pending as a result, without any frequency information.

If you need this information too, I would suggest doing some grouping, like:

string.Join(", ", item.Stuff.Where(e => Condition(e))
  .Select(f => f.Status)
  .GroupBy(status => status)
  .Select(group => string.Format("{0} {1}", group.Count(), group.Key));

this will result in "10 Active, 5 Pending" or an empty string if there are no groups.


EDIT: Now I think of it, string.Join might be a better solution to the original question as well (IEnumerable.Aggregate is a great method, but it might be an overkill). Just something like:

string.Join(", ", item.Stuff.Where(e => Condition(e)).Select(f => f.Status))
查看更多
登录 后发表回答