Miamy
Miamy

Reputation: 2299

How to rewrite two loops into one LINQ statement

I have the next code snippet:

var minArea = float.MaxValue;
foreach (var device in deviceDescriptions)
{
    foreach (var zone in device.Zones)
    {
        if (zone.Area.ValueM > 0 && zone.Area.ValueM < minArea)
            minArea = zone.Area.ValueM;
    }
}

How can I use (if I can) a single LINQ for this?

I'm confusing in using a loop over Zones array.

Thank you in advance.

Upvotes: 0

Views: 84

Answers (3)

Prasad Telkikar
Prasad Telkikar

Reputation: 16079

You can use .SelectMany(),

var minArea = deviceDescriptions.SelectMany(x => x.Zones)  //Flatten Nested list
                 .Where(x => x.Area.ValueM > 0)  //Filter for all positive ValueM
                 .Min(x =>x.Area.ValueM);  //Find Min out of all positive ValueM

SelectMany(): Projects each element of a sequence to an IEnumerable and flattens the resulting sequences into one sequence.

Where(): Filters a sequence of values based on a predicate. In your case predication is all positive ValueM

Min(): Returns the minimum value in a sequence of values.

Upvotes: 3

nvoigt
nvoigt

Reputation: 77364

var minArea = deviceDescriptions.SelectMany(deviceDescription => deviceDescription.Zones)
                                .Where(zone => zone.Area.ValueM > 0)
                                .Min(zone => zone.Area.ValueM);

Upvotes: 1

Nguyễn Văn Phong
Nguyễn Văn Phong

Reputation: 14228

You can use SelectMany() combine with Min() to achieve it.

var result = deviceDescriptions.SelectMany(p => p.Zones).Where(x => x.Area.ValueM > 0))
                                                        .Min(x => x.Area.ValueM);

Projects each element of a sequence to an IEnumerable and flattens the resulting sequences into one sequence

Upvotes: 2

Related Questions