Reputation: 3233
What I'm trying to write is
return possibilities.OrderBy((x, y) =>
{
// returns true or false depending on whether x is
// lexographically smaller than y, e.g. x={1,2,3}
// is lexographically smaller than y={1,3,2}
for(int i = 0; i < x.Length; ++i)
{
if(x[i] < y[i])
return true;
else if(x[i] > y[i])
return false;
}
return true;
})
.First();
where possibilities
is of type IEnumerable<int[]>
. However, I was surprised that this syntax is not valid and that everything I can find by Googling indicates that I would have to write a bunch of extra code to implement an IComparer<int[]>
. Really?
Upvotes: 2
Views: 240
Reputation: 22876
Comparer<T>.Create(Comparison<T>)
can be used in .NET 4.5 or later:
IEnumerable<int[]> a = new[] { new []{ 1, 2 }, new[] { 3, 4 } };
int[] min = a.OrderBy(x => x, Comparer<int[]>.Create((x, y) => {
for (int z, i = 0; i < x.Length; i++)
if ((z = x[i] - y[i]) != 0) return z;
return 0;
})).FirstOrDefault();
But that's not needed to find the minimum:
int[] min = a.Aggregate((x, y) => {
for (int i = 0; i < x.Length; ++i) {
if (x[i] < y[i]) return x;
if (x[i] > y[i]) return y;
}
return x;
});
Upvotes: 5
Reputation: 224
I think an easy way to do it would be
return possibilities.OrderBy(x => String.Join(".",x.ToString.PadLeft(10,'0'))).First();
the reason for the . is to separate the segments, the reason for the pad left to length of 10 with 0s is that the max int is 2 billion, so 10 maximum characters.
Upvotes: -2
Reputation: 101463
You can implement and reuse comparer which accepts compare delegate, like this:
public class DynamicComparer<T> : IComparer<T> {
private readonly Func<T, T, int> _comparer;
public DynamicComparer(Func<T, T, int> comparer) {
_comparer = comparer;
}
public int Compare(T x, T y) {
return _comparer(x, y);
}
}
And then use it in all places you need:
possibilities.OrderBy(c => c, new DynamicComparer<int[]>((x, y) =>
{
for (int i = 0; i < x.Length; ++i)
{
if (x[i] < y[i])
return -1;
else if (x[i] > y[i])
return 1;
}
return 0;
}));
Note that as another answer suggests, there is already such comparer in .NET 4.5, which can be created with Comparer<int[]>.Create
. If you are on .NET 4.5 - no need to create your own comparer like that.
You can even go futher and implement your own OrderBy extension method:
public static class Extensions {
public static IOrderedEnumerable<T> OrderBy<T>(this IEnumerable<T> items, Func<T, T, int> comparer) {
return items.OrderBy(c => c, new DynamicComparer<T>(comparer));
}
}
Then it becomes just like you want:
possibilities.OrderBy((x, y) =>
{
for (int i = 0; i < x.Length; ++i)
{
if (x[i] < y[i])
return -1;
else if (x[i] > y[i])
return 1;
}
return 0;
});
Upvotes: 1