I have a List. I want to print the longest address.
Pseudocode
foreach (var i in listAddr)
{
// access listAddr.Address.Length
// print longest address
// print shortest address
}
I have a List. I want to print the longest address.
Pseudocode
foreach (var i in listAddr)
{
// access listAddr.Address.Length
// print longest address
// print shortest address
}
Very roughly, with no foreach:
var sortedAddr = listAddr.OrderBy(x => x.Address.Length);
var longestAddr = sortedAddr.Last();
var shortedAddr = sortedAddr.First();
As Jon said, this has O(n log n) complexity. But could be reasonable if you don't have extreme performance need.
EDIT:
If you have a lot of same-length addresses you can do this:
var sortedGroups = listAddr.GroupBy(x => x.Address.Length).OrderBy(x => x.Key);
var longestAddresses = sortedGroups.Last();
var shortestAddresses = sortedGroups.First();
// just print iterating over longestAddresses and shortestAddresses ...
It sounds like you want MaxBy
and MinBy
functionality, e.g.
var maxEntry = listAddr.MaxBy(entry => entry.Address.Length);
Console.WriteLine(maxEntry.Address);
var minEntry = listAddr.MinBy(entry => entry.Address.Length);
Console.WriteLine(minEntry.Address);
Unfortunately there's nothing like this in plain LINQ to Objects, but we have an implementation in MoreLINQ and I believe Reactive Extensions has one in System.Interactive too.
Obviously you can sort by address size descending and then take the first result... that will be O(n log n) instead of O(n) complexity... that may well be fine in most cases. It feels inelegant to me though :)
Code from the MoreLINQ implementation of MaxBy
(without comments :)
public static TSource MaxBy<TSource, TKey>(
this IEnumerable<TSource> source,
Func<TSource, TKey> selector)
{
return source.MaxBy(selector, Comparer<TKey>.Default);
}
public static TSource MaxBy<TSource, TKey>(
this IEnumerable<TSource> source,
Func<TSource, TKey> selector, IComparer<TKey> comparer)
{
source.ThrowIfNull("source");
selector.ThrowIfNull("selector");
comparer.ThrowIfNull("comparer");
using (IEnumerator<TSource> sourceIterator = source.GetEnumerator())
{
if (!sourceIterator.MoveNext())
{
throw new InvalidOperationException("Sequence was empty");
}
TSource max = sourceIterator.Current;
TKey maxKey = selector(max);
while (sourceIterator.MoveNext())
{
TSource candidate = sourceIterator.Current;
TKey candidateProjected = selector(candidate);
if (comparer.Compare(candidateProjected, maxKey) > 0)
{
max = candidate;
maxKey = candidateProjected;
}
}
return max;
}
}
}
For ex, if you have a list like that
List<int> myList = new List<int>();
you are able to use myList.Max() and myList.Min() to get max and min values