1

I have this code through which I filter and get a set of groups

var groups = Items.Select(g => g.Category).Distinct(); 

Now in the list I also get a empty group "" which I want to place at the last index in groups.Can someone please tell me how to do this.

slfan
  • 8,950
  • 115
  • 65
  • 78
user505210
  • 1,362
  • 11
  • 28
  • 50
  • why not use .OrderBy(g => g.Category)? – slfan Jan 08 '13 at 06:50
  • Is order by gonna order the groups alphabetically..if that so I don't want that..Distinct is gonna group them as they occur in the items list and that's what I want..The only thing left to do is just move the "" value to the end. – user505210 Jan 08 '13 at 06:54

7 Answers7

3

Not quite, you need double ordering. If you use the above orderby you will get the empty string first.

var groups = Items.Select(g => g.Category).Distinct()
                                          .OrderBy(g => g.Length==0)
                                          .ThenBy(g=>g.Category);

Now the empty group will be last, while the rest will be alphabetically organized.

Habib
  • 219,104
  • 29
  • 407
  • 436
Segev -CJ- Shmueli
  • 1,535
  • 14
  • 15
1

This might help this do without affecting order of category item

var WithoutNull =
(from item in Items
where !string.IsNullOrEmpty(item.Category)
select item.Category).ToList();

var WtihNull=
from item in db.SomeTable
where string.IsNullOrEmpty(item.Category)
select item.Category).ToList();

var allvalues= WithoutNull.Concat(WtihNull)
                                   .ToList();

I think orderby or OrderByDescending clause will do the work for you easily...apply as per your need

var groups = Items.Select(g => g.Category).Distinct().OrderBy(g => g.Key);

or

var groups = Items.OrderBy(g => g.Category).Select(g => g.Category).Distinct();
Pranay Rana
  • 175,020
  • 35
  • 237
  • 263
  • OrderBy will not move the empty string from the list, to the end of the list, instead it will be the first item. – Habib Jan 08 '13 at 06:55
  • Yes, but I am not sure if that is the desired requirement. – Habib Jan 08 '13 at 06:58
  • So all i need is check for a given item in a list having value "" and move it to the last without disturbing the order of the other items. – user505210 Jan 08 '13 at 06:59
  • No guys, the OrderByDescending will also sort the rest of the items from Z-A instead A-Z. Please see my suggestion below. – Segev -CJ- Shmueli Jan 08 '13 at 06:59
1

If you want to preserve the original order then you can try the following.

var temp = Items.Where(r => r.Category != "").Distinct().ToList();
if (Items.Any(r=> r.Category == ""))
    temp.Add("");

Get a list of items without the emptry string Category and then see if your original collection contains and empty group then you can add it to the end of the collection.

Habib
  • 219,104
  • 29
  • 407
  • 436
0

Filter out the empty string (not sure whether it's the name):

var groups = Items.Select(g => g.Category).Where(g => g.Name != "").Distinct(); 

If you need the empty string to be in the list and you do not want to sort, you will have to remove and add it to the end.

slfan
  • 8,950
  • 115
  • 65
  • 78
0

You can create your own IComparator implementation to perform custom ordering. In it, you can decide where to put the empty string as compared to other strings.

See, for instance, here.

Community
  • 1
  • 1
zmbq
  • 38,013
  • 14
  • 101
  • 171
0

OrderBy may work with some clever ordering criteria such as

var groups = Items.Select(g => g.Category).Distinct().OrderBy(
     g => string.IsNullOrEmpty(g.Category) ? 2 : 1);

Essentially, what we are saying is that all groups are equivalent as far as order is concrned except those which are empty (assuming category is key for emptyness). Its still possible that other items might get re-arranged based on the actual sorting algorithm.

EDIT: Tested and above works with in-memory lists. Not sure what will happen when Items is IQueryAble.

VinayC
  • 47,395
  • 5
  • 59
  • 72
0

if you dont want to change the order for rest of collection. you can do it in this way.

 var emptyCategory = Items.Where((r) => r.Category == string.Empty);
 var groups = Items.Where((r) => r.Category != string.Empty).Union(emptyCategory);
D J
  • 6,908
  • 13
  • 43
  • 75