Merge branch 'SequenceComparer' of Common/Utils into dev

This commit is contained in:
Rashod Davis
2018-06-20 19:47:54 +00:00
committed by Gogs
3 changed files with 101 additions and 0 deletions

View File

@@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- Adding SequenceComparer for ordering collections of lists, arrays, etc
## [3.6.0] - 2018-06-19
### Added

View File

@@ -0,0 +1,33 @@
using ICD.Common.Utils.Comparers;
using NUnit.Framework;
namespace ICD.Common.Utils.Tests.Comparers
{
[TestFixture]
public sealed class SequenceComparerTest
{
[Test]
public void CompareTest()
{
SequenceComparer<int> comparer = new SequenceComparer<int>();
// Equal
int[] a = {1, 2, 3};
int[] b = {1, 2, 3};
Assert.AreEqual(0, comparer.Compare(a, b));
// A comes before B
a = new[] {1, 2};
b = new[] {1, 2, 3};
Assert.AreEqual(-1, comparer.Compare(a, b));
// B comes before A
a = new[] { 2, 2, 3 };
b = new[] { 1, 2, 3 };
Assert.AreEqual(1, comparer.Compare(a, b));
}
}
}

View File

@@ -0,0 +1,66 @@
using System;
using System.Collections.Generic;
namespace ICD.Common.Utils.Comparers
{
public sealed class SequenceComparer<T> : IComparer<IEnumerable<T>>
{
private readonly IComparer<T> m_ItemComparer;
/// <summary>
/// Constructor.
/// </summary>
public SequenceComparer()
: this(Comparer<T>.Default)
{
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="comparer"></param>
public SequenceComparer(IComparer<T> comparer)
{
if (comparer == null)
throw new ArgumentNullException("comparer");
m_ItemComparer = comparer;
}
public int Compare(IEnumerable<T> x, IEnumerable<T> y)
{
if (x == null)
throw new ArgumentNullException("x");
if (y == null)
throw new ArgumentNullException("y");
using (IEnumerator<T> firstPos = x.GetEnumerator())
{
using (IEnumerator<T> secondPos = y.GetEnumerator())
{
bool hasFirst = firstPos.MoveNext();
bool hasSecond = secondPos.MoveNext();
while (hasFirst && hasSecond)
{
int result = m_ItemComparer.Compare(firstPos.Current, secondPos.Current);
if (result != 0)
return result;
hasFirst = firstPos.MoveNext();
hasSecond = secondPos.MoveNext();
}
if (!hasFirst && !hasSecond)
return 0;
if (!hasFirst)
return -1;
return 1;
}
}
}
}
}