diff --git a/ShittyLINQ/Last.cs b/ShittyLINQ/Last.cs new file mode 100644 index 0000000..0a93a38 --- /dev/null +++ b/ShittyLINQ/Last.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ShittyLINQ +{ + public static partial class Extensions + { + public static T Last(this IEnumerable self) + { + if (self == null) throw new ArgumentNullException(nameof(self)); + var iterator = self.GetEnumerator(); + if (iterator.MoveNext()) + { + T result; + do + { + result = iterator.Current; + } + while (iterator.MoveNext()); + return result; + } + throw new InvalidOperationException("The source sequence is empty."); + } + + public static T Last(this IEnumerable self, Func predicate) + { + if (self == null || predicate == null) throw new ArgumentNullException(nameof(self)); + + if (self.Count() == 0) throw new InvalidOperationException("The source sequence is empty."); + + self = self.Where(predicate); + + var iterator = self.GetEnumerator(); + if (iterator.MoveNext()) + { + T result; + do + { + result = iterator.Current; + } + while (iterator.MoveNext()); + return result; + } + + throw new InvalidOperationException("No matching element in source sequence."); + } + } +} \ No newline at end of file diff --git a/ShittyLinqTests/LastTests.cs b/ShittyLinqTests/LastTests.cs new file mode 100644 index 0000000..0bafc9e --- /dev/null +++ b/ShittyLinqTests/LastTests.cs @@ -0,0 +1,91 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using ShittyLINQ; +using System; + +namespace ShittyTests +{ + [TestClass] + public class LastTests + { + [TestMethod] + public void Last_GetLastNumber() + { + int[] numbers = new int[] { 1, 2, 3, 4, 5 }; + int expectedResult = 5; + + int result = numbers.Last(); + + Assert.AreEqual(expectedResult, result); + } + + [TestMethod] + public void Last_GetLastNumberMatchingPredicate() + { + int[] numbers = new int[] { 1, 2, 3, 4, 5 }; + int expectedResult = 3; + bool predicate(int i) => i == 3; + + int result = numbers.Last(predicate); + + Assert.AreEqual(expectedResult, result); + } + + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void Last_SourceIsNull() + { + int[] numbers = null; + + int result = numbers.Last(); + } + + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void Last_SourceIsNullWithPredicate() + { + int[] numbers = null; + bool predicate(int i) => i == 3; + + int result = numbers.Last(predicate); + } + + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void Last_PredicateIsNull() + { + int[] numbers = new int[] { 1, 2, 3, 4, 5 }; + Func predicate = null; + + int result = numbers.Last(predicate); + } + + [TestMethod] + [ExpectedException(typeof(InvalidOperationException))] + public void Last_SourceIsEmpty() + { + int[] numbers = new int[] { }; + + int result = numbers.Last(); + } + + [TestMethod] + [ExpectedException(typeof(InvalidOperationException))] + public void Last_SourceIsEmptyWithPredicate() + { + int[] numbers = new int[] { }; + bool predicate(int i) => i == 3; + + int result = numbers.Last(predicate); + } + + [TestMethod] + [ExpectedException(typeof(InvalidOperationException))] + public void Last_NoElementMatchesPredicate() + { + int[] numbers = new int[] { 1, 2, 4, 5 }; + bool predicate(int i) => i == 3; + + int result = numbers.Last(predicate); + } + } +}