diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e56248..788eb59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/ICD.Common.Utils.Tests/Comparers/SequenceComparerTest.cs b/ICD.Common.Utils.Tests/Comparers/SequenceComparerTest.cs new file mode 100644 index 0000000..0f11039 --- /dev/null +++ b/ICD.Common.Utils.Tests/Comparers/SequenceComparerTest.cs @@ -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 comparer = new SequenceComparer(); + + // 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)); + } + } +} diff --git a/ICD.Common.Utils/Comparers/SequenceComparer.cs b/ICD.Common.Utils/Comparers/SequenceComparer.cs new file mode 100644 index 0000000..aac843a --- /dev/null +++ b/ICD.Common.Utils/Comparers/SequenceComparer.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; + +namespace ICD.Common.Utils.Comparers +{ + public sealed class SequenceComparer : IComparer> + { + private readonly IComparer m_ItemComparer; + + /// + /// Constructor. + /// + public SequenceComparer() + : this(Comparer.Default) + { + } + + /// + /// Constructor. + /// + /// + public SequenceComparer(IComparer comparer) + { + if (comparer == null) + throw new ArgumentNullException("comparer"); + + m_ItemComparer = comparer; + } + + public int Compare(IEnumerable x, IEnumerable y) + { + if (x == null) + throw new ArgumentNullException("x"); + + if (y == null) + throw new ArgumentNullException("y"); + + using (IEnumerator firstPos = x.GetEnumerator()) + { + using (IEnumerator 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; + } + } + } + } +}