Example #1
0
        public static bool ContainsRange <T>(this SCG.IEnumerable <T> first, SCG.IEnumerable <T> second, SCG.IEqualityComparer <T> equalityComparer = null)
        {
            #region Code Contracts

            // Argument must be non-null
            Requires(first != null, ArgumentMustBeNonNull);

            // Argument must be non-null
            Requires(second != null, ArgumentMustBeNonNull);


            // first remains unchanged
            Ensures(first == null || first.IsSameSequenceAs(OldValue(first.ToList())));

            // second remains unchanged
            Ensures(second == null || second.IsSameSequenceAs(OldValue(second.ToList())));

            #endregion

            var firstArray  = first.ToArray();
            var secondArray = second.ToArray();

            if (firstArray.Length < secondArray.Length)
            {
                return(false);
            }

            // Use default comparer if none is supplied
            if (equalityComparer == null)
            {
                equalityComparer = SCG.EqualityComparer <T> .Default;
            }

            // Sort based on hash code
            Comparison <T> hashCodeComparison = (x, y) => equalityComparer.GetHashCode(x).CompareTo(equalityComparer.GetHashCode(y));
            Array.Sort(firstArray, hashCodeComparison);
            Array.Sort(secondArray, hashCodeComparison);

            for (var j = 0; j < secondArray.Length; j++)
            {
                var found         = false;
                var secondElement = secondArray[j];

                for (var i = j; i < firstArray.Length; i++)
                {
                    var firstElement = firstArray[i];

                    var comparison = hashCodeComparison(firstElement, secondElement);

                    // Equal doesn't exist
                    if (comparison > 0)
                    {
                        break;
                    }

                    if (comparison == 0 && equalityComparer.Equals(firstElement, secondElement))
                    {
                        firstArray.Swap(i, j);
                        // TODO: the hash codes are not necessarily ordered after swapping the items

                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    return(false);
                }

                // Invariant: all items up to and including j are equal pairwise in the two arrays
                Assume(ForAll(0, j + 1, i => equalityComparer.Equals(firstArray[i], secondArray[i])));
            }

            return(true);
        }
Example #2
0
        public static bool UnsequenceEqual <T>(this SCG.IEnumerable <T> first, SCG.IEnumerable <T> second, SCG.IEqualityComparer <T> comparer = null)
        {
            #region Code Contracts

            // first remains unchanged
            Ensures(first == null || first.IsSameSequenceAs(OldValue(first.ToList())));

            // second remains unchanged
            Ensures(second == null || second.IsSameSequenceAs(OldValue(second.ToList())));

            #endregion

            if (ReferenceEquals(first, second))
            {
                return(true);
            }

            if (first == null || second == null)
            {
                return(false);
            }

            var firstArray  = first.ToArray();
            var secondArray = second.ToArray();

            if (firstArray.Length != secondArray.Length)
            {
                return(false);
            }

            // Use default comparer if none is supplied
            if (comparer == null)
            {
                comparer = SCG.EqualityComparer <T> .Default;
            }

            // Sort based on hash code
            Comparison <T> hashCodeComparison = (x, y) => comparer.GetHashCode(x).CompareTo(comparer.GetHashCode(y));
            Array.Sort(firstArray, hashCodeComparison);
            Array.Sort(secondArray, hashCodeComparison);

            for (var i = 0; i < firstArray.Length; i++)
            {
                var found        = false;
                var firstElement = firstArray[i];

                for (var j = i; j < secondArray.Length; j++)
                {
                    var secondElement = secondArray[j];

                    if (hashCodeComparison(firstElement, secondElement) != 0)
                    {
                        break;
                    }

                    if (comparer.Equals(firstElement, secondElement))
                    {
                        secondArray.Swap(i, j);

                        // Continue with next element in first array
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    return(false);
                }
            }

            return(true);
        }