namespace Cobra.Core extend System.Collections.IEnumerable def join(sep as String) as String """ Join the items in an IEnumerable collection separated by a string. """ test assert ['a', 'b'].join('.') == 'a.b' assert ['a'].join('.') == 'a' assert [1, 2].join(', ') == '1, 2' assert [1, 2].join('') == '12' assert [].join('.') == '' body sb = StringBuilder() s = '' for item in this sb.append(s) sb.append(CobraCore.printStringMaker.makeString(item)) s = sep return sb.toString def join(sep as String, lastSep as String) as String """ Join the items in an IEnumerable collection with a separator string except for the last two items; join them with the lastSep string """ test assert ['a', 'b'].join(', ', ' and ') == 'a and b' assert ['a', 'b', 'c'].join(', ', ' and ') == 'a, b and c' assert ['a', 'b', 'c', 'd'].join(', ', ' and ') == 'a, b, c and d' assert [1, 2, 3, 4].join(', ', ' and ') == '1, 2, 3 and 4' assert [1].join('.', ':') == '1' assert [1, 2].join('', '') == '12' assert [].join('.', ':') == '' body sb = StringBuilder() s = '' items = [] for item in this, items.add(item) count = items.count for i in count sb.append(s) sb.append(items[i].toString) s = if(i==count-2, lastSep, sep) return sb.toString extend IEnumerable def first as T for item in this, return item throw InvalidOperationException('the sequence is empty') def take(count as int) as T* require count >= 0 body if count < 1, yield break for i, value in .numbered if i < count, yield value else, break def skip(count as int) as T* require count >= 0 body for i, value in .numbered if i >= count, yield value def toList as List """ Turn an IEnumerable of T into a list of T. """ return List(this) def numbered as KeyValuePair* """ Returns a stream of pairs of (index, value). Can be used like so: for i, value in someList.numbered ... """ # could use other overload, but saving a method call i = 0 for item in this yield KeyValuePair(i, item) i += 1 def numbered(start as int) as KeyValuePair* """ Returns a stream of pairs of (index, value) where the first index == start. Can be used like so: for i, value in someList.numbered ... """ i = start for item in this yield KeyValuePair(i, item) i += 1 /# TODO: cannot do the following yet due to a bug in extensions and how they are chosen with respect to inheritance these are available in lists though, so you can use .toList above http://cobra-language.com/trac/cobra/ticket/130 def last as T for item in this, pass return item def reversed as List return .toList.reversed def sorted as List return .toList.sorted def sorted(comparison as Comparison) as List # TODO: needs a test case return .toList.sorted(comparison) def sorted(comparer as Comparer) as List # TODO: needs a test case return .toList.sorted(comparer) #/ class TestIEnumerableExtensions shared def stuff as int* """ Returns 2, 1, 3 in that order. """ yield 2 yield 1 yield 3 def empty as int* yield break test t = .stuff.toList assert t.count == 3 and t == [2, 1, 3] /# assert .stuff.last == 3 # TODO: test .numbered t = .stuff.reversed assert t.count == 3 and t == [3, 1, 2] t = .stuff.sorted assert t.count == 3 and t == [1, 2, 3] #/ t = .empty.toList assert t.count == 0 and t == [] /# # TODO: test .numbered assert .empty.reversed == [] assert .empty.sorted == [] #/ test first assert [1, 2].first == 1 expect InvalidOperationException [].first test take assert [1, 2].take(0).toList.count == 0 assert [1, 2, 3, 4].take(3).toList == [1, 2, 3] assert [1, 2, 3, 4].take(10).toList == [1, 2, 3, 4] assert [].take(5).toList.count == 0 test skip assert [1, 2].skip(0).toList == [1, 2] assert [1, 2].skip(2).toList.count == 0 assert [1, 2].skip(3).toList.count == 0 assert [].skip(0).toList.count == 0 assert [].skip(1).toList.count == 0