7 public static class CollectionHelper
8 {
9 public static IEnumerable<T> Enumerate<T>(params T[] args)
10 {
11 if (args == null)
12 throw new ArgumentNullException("args");
13
14 foreach (T arg in args)
15 yield return arg;
16 }
17
18 public static T First<T>(IEnumerable<T> source)
19 {
20 return First(source, ReturnTrue);
21 }
22
23 public static T First<T>(IEnumerable<T> source, Func<T, bool> predicate)
24 {
25 T result;
26 if (!TryFindFirst(source, out result, predicate))
27 throw new InvalidOperationException("Source sequence empty or no items satisfy predicate.");
28
29 return result;
30 }
31
32 public static T FirstOrDefault<T>(IEnumerable<T> source)
33 {
34 return FirstOrDefault(source, ReturnTrue);
35 }
36
37 public static T FirstOrDefault<T>(IEnumerable<T> source, Func<T, bool> predicate)
38 {
39 T result;
40 TryFindFirst(source, out result, predicate);
41 return result;
42 }
43
44 public static bool TryFindFirst<T>(IEnumerable<T> source, out T result)
45 {
46 return TryFindFirst(source, out result, ReturnTrue);
47 }
48
49 public static bool TryFindFirst<T>(IEnumerable<T> source, out T result, Func<T, bool> predicate)
50 {
51 if (source == null)
52 throw new ArgumentNullException("source");
53 if (predicate == null)
54 throw new ArgumentNullException("predicate");
55
56 foreach (T item in source)
57 {
58 if (predicate(item))
59 {
60 result = item;
61 return true;
62 }
63 }
64
65 result = default(T);
66 return false;
67 }
68
69 public static IEnumerable<TOut> Map<T, TOut>(IEnumerable<T> source, Func<T, TOut> converter)
70 {
71 if (source == null)
72 throw new ArgumentNullException("source");
73 if (converter == null)
74 throw new ArgumentNullException("fn");
75
76 foreach (T item in source)
77 yield return converter(item);
78 }
79
80 public static IEnumerable<TOut> Zip<TLeft, TRight, TOut>(IEnumerable<TLeft> left, IEnumerable<TRight> right, Func<TLeft, TRight, TOut> fn)
81 {
82 if (left == null)
83 throw new ArgumentNullException("left");
84 if (right == null)
85 throw new ArgumentNullException("right");
86 if (fn == null)
87 throw new ArgumentNullException("fn");
88
89 using (IEnumerator<TLeft> leftEnumerator = left.GetEnumerator())
90 using (IEnumerator<TRight> rightEnumerator = right.GetEnumerator())
91 {
92 while (true)
93 {
94 bool leftMoved = leftEnumerator.MoveNext();
95
96 if (!(leftMoved == rightEnumerator.MoveNext()))
97 throw new InvalidOperationException("Sequences are of incompatible lengths.");
98
99 if (!leftMoved)
100 break;
101
102 yield return fn(leftEnumerator.Current, rightEnumerator.Current);
103 }
104 }
105 }
106
107 private static bool ReturnTrue<T>(T ignored)
108 {
109 return true;
110 }
111 }