Using IComparer to compare 2 IEnumerables with 1 comp obj

264 Views Asked by At

I'm looking for a way to create a method which should compare for example 2 strings with 1 comparable string and return 1, 0 or -1 (if the value is greater than, equal to, or less than). The method should look like this:

int CompareEnumerables<T>(IEnumerable<T> xs, IEnumerable<T> ys, IComparer<T> comp)

This is the condition: write method (method of general comparison of 2 random sequences (the objects of which are of the same type allowing comparison))

int CompareEnumerables<T>(IEnumerable<T> xs, IEnumerable<T> ys, iComparer<T> comp) 

to return -1, 0 or 1 depending on which a series of lexicographical precedes the other.

Any idea how to do so? I tried a few times. If needed I will share code.

1

There are 1 best solutions below

0
Richard Deeming On

How about something like this:

public class SequenceComparer<T> : IComparer<IEnumerable<T>>
{
    public SequenceComparer(IComparer<T> inner = default)
    {
        Inner = inner ?? Comparer<T>.Default;
    }
    
    public IComparer<T> Inner { get; }
    
    public int Compare(IEnumerable<T> left, IEnumerable<T> right)
    {
        if (left is null) throw new ArgumentNullException(nameof(left));
        if (right is null) throw new ArgumentNullException(nameof(right));
        
        using (var leftEnum = left.GetEnumerator())
        using (var rightEnum = right.GetEnumerator())
        {
            bool leftRunning = leftEnum.MoveNext();
            bool rightRunning = rightEnum.MoveNext();
            while (leftRunning && rightRunning)
            {
                int result = Inner.Compare(leftEnum.Current, rightEnum.Current);
                if (result != 0) return result;
                
                leftRunning = leftEnum.MoveNext();
                rightRunning = rightEnum.MoveNext();
            }
            
            if (leftRunning) return 1;
            if (rightRunning) return -1;
            return 0;
        }
    }
}
static int CompareEnumerables<T>(IEnumerable<T> xs, IEnumerable<T> ys, IComparer<T> comp)
{
    var comparer = new SequenceComparer<T>(comp);
    return comparer.Compare(xs, vs);
}