Skip to content

Commit

Permalink
feat: foreach method (#84)
Browse files Browse the repository at this point in the history
changes:
- `ForEach` method with break condition added
- unit test added
- some small fixes
- version bump to `2.1.0`

closes #83
  • Loading branch information
BoBoBaSs84 authored Feb 8, 2024
2 parents d76b5d2 + 5a8aaf9 commit 2142051
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 24 deletions.
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<VersionMajor>2</VersionMajor>
<VersionMinor>0</VersionMinor>
<VersionMinor>1</VersionMinor>
<VersionPatch>0</VersionPatch>
<VersionPrefix>$(VersionMajor).$(VersionMinor).$(VersionPatch)</VersionPrefix>
<VersionSuffix Condition="$(Configuration.Equals('Debug'))">Development</VersionSuffix>
Expand Down
43 changes: 33 additions & 10 deletions src/BB84.Extensions/EnumerableExtensions.ForEach.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,50 @@
public static partial class EnumerableExtensions
{
/// <summary>
/// Iterates over an enumerable and executes an action on each element.
/// Iterates over the <paramref name="values"/> and executes an <paramref name="action"/>
/// on each element.
/// </summary>
/// <typeparam name="T">The type of the elements of source.</typeparam>
/// <param name="items">A sequence of values to invoke an action on.</param>
/// <param name="values">A sequence of values to invoke an action on.</param>
/// <param name="action">The action to invoke on each source element.</param>
public static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
public static void ForEach<T>(this IEnumerable<T> values, Action<T> action)
{
foreach (T item in items)
action(item);
foreach (T value in values)
action(value);
}

/// <summary>
/// Iterates over an enumerable and executes an action on each element.
/// Iterates over the <paramref name="values"/> that fit the <paramref name="predicate"/>
/// and executes an <paramref name="action"/> on each element.
/// </summary>
/// <typeparam name="T">The type of the elements of source.</typeparam>
/// <param name="items">A sequence of values to invoke an action on.</param>
/// <param name="values">A sequence of values to invoke an action on.</param>
/// <param name="predicate">The function to test each element for a condition.</param>
/// <param name="action">The action to invoke on each source element.</param>
public static void ForEach<T>(this IEnumerable<T> items, Func<T, bool> predicate, Action<T> action)
public static void ForEach<T>(this IEnumerable<T> values, Func<T, bool> predicate, Action<T> action)
{
foreach (T item in items.Where(predicate))
action(item);
foreach (T value in values.Where(predicate))
action(value);
}

/// <summary>
/// Iterates over the <paramref name="values"/> that fit the <paramref name="predicate"/>
/// and executes an <paramref name="action"/> on each element if the
/// <paramref name="breakCondition"/> is not met.
/// </summary>
/// <typeparam name="T">The type of the elements of source.</typeparam>
/// <param name="values">A sequence of values to invoke an action on.</param>
/// <param name="predicate">The function to test each element for a condition.</param>
/// <param name="breakCondition">The condition that breaks the iteration.</param>
/// <param name="action">The action to invoke on each source element.</param>
public static void ForEach<T>(this IEnumerable<T> values, Func<T, bool> predicate, Func<T, bool> breakCondition, Action<T> action)
{
foreach (T value in values.Where(predicate))
{
if (breakCondition(value))
break;

action(value);
}
}
}
4 changes: 4 additions & 0 deletions src/BB84.Extensions/ObjectExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,5 +82,9 @@ public static long ToInt64Invariant(this object? value)
/// <returns>The string representation of value, or <see cref="string.Empty"/> if value is an object
/// whose value is null. If value is null, the method returns <see cref="string.Empty"/>.</returns>
public static string ToStringInvariant(this object? value)
#if NET5_0_OR_GREATER
=> Convert.ToString(value, CultureInfo.InvariantCulture) ?? string.Empty;
#else
=> Convert.ToString(value, CultureInfo.InvariantCulture);
#endif
}
2 changes: 1 addition & 1 deletion src/BB84.Extensions/Serialization/XmlExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public static T FromXml<T>(this string xmlValue, XmlReaderSettings? settings = n
/// <returns>The XML string representation of the object <typeparamref name="T"/>.</returns>
public static string ToXml<T>(this T value, XmlSerializerNamespaces? namespaces = null, XmlWriterSettings? settings = null) where T : class
{
namespaces ??= new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty });
namespaces ??= new XmlSerializerNamespaces([XmlQualifiedName.Empty]);
settings ??= WriterSettings;

using StringWriterWithEncoding stream = new(settings.Encoding);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public sealed partial class ArrayExtensionsTests
[TestMethod]
public void RandomChoice()
{
int[] ints = { 1, 2, 3 };
int[] ints = [1, 2, 3];

int i = ints.RandomChoice();

Expand Down
2 changes: 1 addition & 1 deletion tests/BB84.ExtensionsTests/ByteExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public partial class ByteExtensionsTests
[TestMethod]
public void GetHexStringTest()
{
byte[] bytes = { 255, 255 };
byte[] bytes = [255, 255];

string result = bytes.GetHexString();

Expand Down
11 changes: 11 additions & 0 deletions tests/BB84.ExtensionsTests/EnumerableExtensionsTests.ForEach.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,15 @@ public void ForEachWithPredicateTest()

Assert.AreEqual(2, hits);
}

[TestMethod]
public void ForEachWithPredicateAndBreakTest()
{
int hits = default;
IEnumerable<string> strings = new List<string>() { "a", "ab", "b", "bb" };

strings.ForEach(x => x.Contains('b'), x=> x.StartsWith("b", StringComparison.OrdinalIgnoreCase), x => hits++);

Assert.AreEqual(1, hits);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,9 @@ namespace BB84.ExtensionsTests;

public sealed partial class ObjectExtensionsTests
{
[TestMethod("Object to invariant string test")]
public void ToStringInvariant()
{
object obj = "UnitTest";

string s = obj.ToStringInvariant();

Assert.AreEqual("UnitTest", s);
}
[DataTestMethod("Object to invariant string test")]
[DataRow("UnitTest", "UnitTest")]
[DataRow(null, "")]
public void ToStringInvariant(object value, string expected)
=> Assert.AreEqual(expected, value.ToStringInvariant());
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ public class XmlExtensionTests
private const string XmlTextString = @"<Fancy Id=""348798ee-12f2-4a20-b030-756bb6a4134d""><Name>UnitTestName</Name><Description>UnitTestDescription</Description></Fancy>";

private readonly XmlWriterSettings _writerSettings = new();
private readonly XmlReaderSettings _readerSettings = new();

[TestMethod]
public void FromXmlTest()
Expand Down

0 comments on commit 2142051

Please sign in to comment.