1

I have a List of type RGBComparison which I created. It has euclidean distance, id, local id, etc as variables. After I sort the List by distances I have an output like this;

1.35363 id=3 
1.43554 id=2 
1.4556  id=3
1.5  id = 35
1.6 id = 2

======================================

etc. They are sub images' euclidean distances(variable name distance) from the input subimage. I want to group them by keeping the original order. Consider there are 8 distances from image id 1 (and image id 1 is the closest one, 1st one in the list). I want an output like

    1.35363 id=3
    1.4556  id=3
    1.43554 id=2
    1.6 id=2
    1.5 id = 35

....

Is there a way to do this? Also I will only take max 5 distances from an input. For example, if id 1 has 8 submage distances in the List, then I will only take the first 5. Later I will show these subimages on the original image.

I would really appreciate any help.

Ada
  • 614
  • 3
  • 17
  • 31
  • http://stackoverflow.com/questions/298725/linq-multiple-order-by I'd say duplicate but the only taking 5 from a group makes this interesting – itchi May 04 '11 at 15:39
  • thank you for the link. would that solution keep the original order? – Ada May 04 '11 at 15:44

2 Answers2

1

If your have your data in a list distances you can use a combination of OrderBy/GroupBy, Take and finally SelectMany to flatten the result list:

var results = distances.OrderBy( x=> x.Id)
                       .GroupBy(x => x.Id)
                       .Select(g => g.OrderBy(x => x.Distance).Take(5))
                       .SelectMany(x => x)
                       .ToList() ;

To limit the number of distances to 5 max for each Id you do need the grouping, also use of an OrderBy before the grouping to induce the correct order of Ids which is preserved by the grouping.

Edit in response to comment and clarification:

   var results = distances.GroupBy(x => x.Id)
                          .Select(g => g.OrderBy(x => x.Distance).Take(5))
                          .SelectMany(x => x)
                          .OrderBy( x=> x.Distance)
                          .ToList();

This should give you a list sorted by distance, with at most 5 elements for any id.

BrokenGlass
  • 149,257
  • 27
  • 271
  • 318
  • I don't know how to use the output. I never used "var" before. How am I going to use the output results? I printed whats in it and it was consisted of mainscreen+ sth. – Ada May 04 '11 at 16:12
  • you can replace `var results` with `List results`, also its assumed distances is of type `List` – BrokenGlass May 04 '11 at 16:15
  • it doesnt keep the order. Gives very long distances on top of the list. – Ada May 04 '11 at 16:20
  • it sorts the id's, puts the smallest one on top but what I need is based on the distance, and then id's. Wish I knew anything about group by – Ada May 04 '11 at 16:23
  • perhaps I made a mistake by giving a biased example. 1.3434 id=35, 1.35656 id=1 is also an output. – Ada May 04 '11 at 16:26
  • I changed the example outputs in the question. – Ada May 04 '11 at 16:29
  • The output is grouped by id, for a given id the distances are sorted ascending, max 5 elements - if you wanted something else your example is confusing, since the output is clearly sorted by id first, then by distance. Please clarify. – BrokenGlass May 04 '11 at 16:31
  • I changed your code to accept If your have your data in a list distances you can use a combination of OrderBy/GroupBy, Take and finally SelectMany to flatten the result list: var results = distances.OrderBy( x=> x.distance) .GroupBy(x => x.Id) .Select(g => g.OrderBy(x => x.Distance).Take(5)) .SelectMany(x => x) .ToList() ; Now it works! – Ada May 04 '11 at 16:35
  • Thank you I hope my change in the code is true. I only did it by trying but according to the new examples, could the new code populate the right list? – Ada May 04 '11 at 16:37
0

you can use LINQ to sort your list pretty easily

var myRGBComparisonList = new List<RGBComparison>();
//... populate list somewhere
var sortedSequence = from rgbComparison in myRGBComparisonList
                     orderby rgbComparison.ID ascending, rgbComparison.Distance ascending
                     select rgbComparison;
dmg
  • 560
  • 7
  • 14