zoukankan      html  css  js  c++  java
  • IEnumerable的扩展方法

           近期收集一些基于IEnumerable<T>扩展方法,它给我们带了很多便利,有时的确是实用的。其中有Alternate,Append,Prepend,Distinct,Contains。具体怎么用呢,看下面的UnitTest.

    Code:

        /// <summary>
        /// IEnumerableExtension
        /// </summary>
        public static class IEnumerableExtensions
        {
            #region Methods (5) 
     
            // Public Methods (5) 
     
            /// <summary>
            /// Alternates the specified first.
            /// </summary>
            /// <typeparam name="TSource">The type of the source.</typeparam>
            /// <param name="first">The first.</param>
            /// <param name="second">The second.</param>
            /// <returns></returns>
            public static IEnumerable<TSource> Alternate<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second)
            {
                using (IEnumerator<TSource> e1 = first.GetEnumerator())
                using (IEnumerator<TSource> e2 = second.GetEnumerator())
                    while (e1.MoveNext() && e2.MoveNext())
                    {
                        yield return e1.Current;
                        yield return e2.Current;
                    }
            }
     
            /// <summary>
            /// Appends the specified source.
            /// </summary>
            /// <typeparam name="TSource">The type of the source.</typeparam>
            /// <param name="source">The source.</param>
            /// <param name="element">The element.</param>
            /// <returns>IEnumerable<TSource></returns>
            public static IEnumerable<TSource> Append<TSource>(this IEnumerable<TSource> source, TSource element)
            {
                using (IEnumerator<TSource> e1 = source.GetEnumerator())
                    while (e1.MoveNext())
                        yield return e1.Current;
     
                yield return element;
            }
     
            /// <summary>
            /// Determines whether [contains] [the specified source].
            /// </summary>
            /// <typeparam name="TSource">The type of the source.</typeparam>
            /// <typeparam name="TResult">The type of the result.</typeparam>
            /// <param name="source">The source.</param>
            /// <param name="value">The value.</param>
            /// <param name="selector">The selector.</param>
            /// <returns>
            ///     <c>true</c> if [contains] [the specified source]; otherwise, <c>false</c>.
            /// </returns>
            public static bool Contains<TSource, TResult>(
                this IEnumerable<TSource> source, TResult value, Func<TSource, TResult> selector)
            {
                foreach (TSource sourceItem in source)
                {
                    TResult sourceValue = selector(sourceItem);
                    if (sourceValue.Equals(value))
                        return true;
                }
                return false;
            }
     
            /// <summary>
            /// Distincts the specified source.
            /// </summary>
            /// <typeparam name="TSource">The type of the source.</typeparam>
            /// <typeparam name="TResult">The type of the result.</typeparam>
            /// <param name="source">The source.</param>
            /// <param name="comparer">The comparer.</param>
            /// <returns>IEnumerable<TSource></returns>
            public static IEnumerable<TSource> Distinct<TSource, TResult>(
         this IEnumerable<TSource> source, Func<TSource, TResult> comparer)
            {
                return source.Distinct(new DynamicComparer<TSource, TResult>(comparer));
            }
     
            /// <summary>
            /// Prepends the specified source.
            /// </summary>
            /// <typeparam name="TSource">The type of the source.</typeparam>
            /// <param name="source">The source.</param>
            /// <param name="element">The element.</param>
            /// <returns>IEnumerable<TSource></returns>
            public static IEnumerable<TSource> Prepend<TSource>(this IEnumerable<TSource> source, TSource element)
            {
                yield return element;
     
                using (IEnumerator<TSource> e1 = source.GetEnumerator())
                    while (e1.MoveNext())
                        yield return e1.Current;
            }
     
            #endregion Methods 
        }
        /// <summary>
        /// DynamicComparer
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TResult">The type of the result.</typeparam>
        public class DynamicComparer<T, TResult> : IEqualityComparer<T>
        {
            #region Fields (1) 
     
            private readonly Func<T, TResult> _selector;
     
            #endregion Fields 
     
            #region Constructors (1) 
     
            /// <summary>
            /// Initializes a new instance of the <see cref="DynamicComparer&lt;T, TResult&gt;"/> class.
            /// </summary>
            /// <param name="selector">The selector.</param>
            public DynamicComparer(Func<T, TResult> selector)
            {
                _selector = selector;
            }
     
            #endregion Constructors 
     
            #region Methods (2) 
     
            // Public Methods (2) 
     
            /// <summary>
            /// Determines whether the specified objects are equal.
            /// </summary>
            /// <param name="x">The first object of type <paramref name="T"/> to compare.</param>
            /// <param name="y">The second object of type <paramref name="T"/> to compare.</param>
            /// <returns>
            /// true if the specified objects are equal; otherwise, false.
            /// </returns>
            public bool Equals(T x, T y)
            {
                TResult result1 = _selector(x);
                TResult result2 = _selector(y);
                return result1.Equals(result2);
            }
     
            /// <summary>
            /// Returns a hash code for the specified object.
            /// </summary>
            /// <param name="obj">The <see cref="T:System.Object"/> for which a hash code is to be returned.</param>
            /// <returns>A hash code for the specified object.</returns>
            /// <exception cref="T:System.ArgumentNullException">
            /// The type of <paramref name="obj"/> is a reference type and <paramref name="obj"/> is null.
            /// </exception>
            public int GetHashCode(T obj)
            {
                TResult result = _selector(obj);
                return result.GetHashCode();
            }
     
            #endregion Methods 
        }

    UnitTest:

       1:      #region Methods (8) 
       2:   
       3:          // Public Methods (7) 
       4:   
       5:          [Test]
       6:          public void Bad_concat_method()
       7:          {
       8:              var ints = new[] { 1, 2, 3 };
       9:   
      10:              var oneToFour = ints.Concat(Enumerable.Repeat(4, 1));
      11:   
      12:              CollectionAssert.AreEqual(new[] { 1, 2, 3, 4 }, oneToFour.ToArray());
      13:          }
      14:   
      15:          [Test]
      16:          public void Better_enumerable_extensions()
      17:          {
      18:              var values = new[]
      19:                               {
      20:                                   new Person {FirstName = "Bob", LastName = "Smith"},
      21:                                   new Person {FirstName = "Don", LastName = "Allen"},
      22:                                   new Person {FirstName = "Bob", LastName = "Sacamano"},
      23:                                   new Person {FirstName = "Chris", LastName = "Smith"},
      24:                                   new Person {FirstName = "George", LastName = "Allen"}
      25:                               };
      26:   
      27:              Assert.AreEqual(3, values.Distinct(person => person.LastName).Count());
      28:              Assert.AreEqual(4, values.Distinct(person => person.FirstName).Count());
      29:              Assert.IsTrue(values.Contains("Smith", person => person.LastName));
      30:              Assert.IsFalse(values.Contains("Nixon", person => person.LastName));
      31:          }
      32:   
      33:          [Test]
      34:          public void Easier_concat_with_append()
      35:          {
      36:              var ints = new[] { 1, 2, 3 };
      37:   
      38:              var oneToFour = ints.Append(4);
      39:   
      40:              CollectionAssert.AreEqual(new[] { 1, 2, 3, 4 }, oneToFour.ToArray());
      41:          }
      42:   
      43:          [Test]
      44:          public void Easier_concat_with_prepend()
      45:          {
      46:              var ints = new[] { 1, 2, 3 };
      47:   
      48:              var zeroToThree = ints.Prepend(0);
      49:   
      50:              CollectionAssert.AreEqual(new[] { 0, 1, 2, 3 }, zeroToThree.ToArray());
      51:          }
      52:   
      53:          [Test]
      54:          public void TestAggregate()
      55:          {
      56:              string sentence = "the quick brown fox jumps over the lazy dog";
      57:   
      58:              // Split the string into individual words.
      59:              string[] words = sentence.Split(' ');
      60:   
      61:              // Prepend each word to the beginning of the 
      62:              // new sentence to reverse the word order.
      63:              string reversed = words.Aggregate((workingSentence, next) =>
      64:                                                    next + " " + workingSentence);
      65:              Assert.AreEqual("dog lazy the over jumps fox brown quick the",reversed);
      66:          }
      67:   
      68:          [Test]
      69:          public void TestintArray()
      70:          {
      71:              int[] aa = new int[] { 1, 3, 5};
      72:              int[] bb = new int[] { 2, 4, 6 };
      73:   
      74:              var cc = aa.Alternate(bb);
      75:   
      76:              CollectionAssert.AreEqual(new[] { 1, 2, 3, 4, 5, 6},cc.ToArray());
      77:   
      78:          }
      79:   
      80:          [Test]
      81:          public void Word_play()
      82:          {
      83:              var source = new[] { "That", "is", "exactly", "I", "want" };
      84:   
      85:              var result = source.Alternate(Spaces()).Aggregate(string.Empty, (a, b) => a + b);
      86:   
      87:             
      88:              foreach (var s in result)
      89:              {
      90:                  Console.Write(s);
      91:              }
      92:              //That is exactly I want 
      93:          }
      94:          // Private Methods (1) 
      95:   
      96:          private IEnumerable<string> Spaces()
      97:          {
      98:              while (true)
      99:                  yield return " ";
     100:          }
     101:   
     102:          #endregion Methods 

    Author:Petter Liu   http://wintersun.cnblogs.com  

    希望这篇Post对您有帮助。

  • 相关阅读:
    (转) mysql的分区技术 .
    (转) MySQL中索引的限制
    单键索引还是组合索引
    什么是挂载?mount的用处在哪?
    java中的try-catch-finally中的return的执行顺序
    eclipse中spring配置文件的自动提示和namespace的添加
    try catch 语句中有return 的各类情况
    IOC与DI的理解
    对已经存在的没有唯一标识的表添加一个自增的id字段(利用序列sequence)操作过程
    mysql5.7导出数据提示--secure-file-priv选项问题的解决方法
  • 原文地址:https://www.cnblogs.com/wintersun/p/1597542.html
Copyright © 2011-2022 走看看