3

I have below class -

  public class Test
    {
        public string TestServerName;
        public string TestApplicationRunning;
        public bool IsAvailable;
        public long Counter;
    }

How to get the items with lowest counter value using LINQ?

Suppose lowest counter value is 0 in all items then LINQ should return all items with Counter value 0.There can be more then 1 items with counter value minimum.

Nitendra Jain
  • 489
  • 1
  • 7
  • 24
  • 1
    Had you tried something before asking, it could've been a better question – Ghasem Feb 09 '16 at 07:32
  • 1
    Probably duplicate of http://stackoverflow.com/questions/914109/how-to-use-linq-to-select-object-with-minimum-or-maximum-property-value and http://stackoverflow.com/questions/2736236/how-to-use-linq-to-find-the-minimum – xanatos Feb 09 '16 at 07:36

5 Answers5

6

You can use Min extension method and then filter source with the help of Where extension method:

var minValue = source.Min(x => x.Counter);
var result = source.Where(x => x.Counter == minValue).ToList();

Don't forget to include Systme.Linq namespace. BTW, with this approach, you will execute two queries to the source.

Farhad Jabiyev
  • 26,014
  • 8
  • 72
  • 98
  • Above example is good as total iterations will be `2 x length of source`. Instead of combining these 2 queries and then iterations will be `length of source x length of source` – Nikhil Agrawal Feb 09 '16 at 07:31
0

You could also do :

source.GroupBy(x=>x.Counter)
      .OrderBy(x=>x.Key)
      .Take(1)
      .Select(x=>x).ToList();

though it's not as obvious as Fᴀʀhad's solution :)

sirrocco
  • 7,975
  • 4
  • 59
  • 81
0

Try this example:

List<Test> lstTests = new lstTests();
Test test1 = new Test();
Test test2 = new Test();
Test test3 = new Test();

test1.Counter = 3;
test2.Counter = 4;
test3.Counter = 3;

lstTests.Add(test1);
lstTests.Add(test2);
lstTests.Add(test3);


var valMin = lstTests.Min(m => m.Counter);
var results = source.Where(x => x.Counter == valMin).ToList();

OR

var result = source.Where(x => x.Counter == valMin).FirstOrDefault();

If u want the first occurance Use FirstOrDefault.

rdn87
  • 739
  • 5
  • 18
0

With below query you can find nth lowest value

int ix = 1;
var orderedSource  = source.OrderBy(i => i.counter).Select(y => new { rank =ix++ , value = y });

you pass any value instead of N to get nth lowest value

int N = 4;
var  result  = orderedSource.Where(x=>x.rank == N).FirstOrDefault();
Test testValue = result.value; 
Viru
  • 2,228
  • 2
  • 17
  • 28
0

You can use the MinBy (or MaxBy) extension method from MoreLinq.

As from this issue, the min by functionality change to return IEnumerable of T (if to be more precise: IExtremaEnumerable) instead of only one T item to:

public static IExtremaEnumerable<TSource> MinBy<TSource, TKey>(this IEnumerable<TSource> source,
        Func<TSource, TKey> selector, IComparer<TKey> comparer)

Usage Example:

using MoreLinq;

IEnumerable<Test> testList = source.MinBy(p => p.Counter);
Shahar Shokrani
  • 7,598
  • 9
  • 48
  • 91