-
Notifications
You must be signed in to change notification settings - Fork 0
Homework 7 - [Map, Filter, Fold]
#5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <TargetFramework>net9.0</TargetFramework> | ||
| <LangVersion>latest</LangVersion> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <Nullable>enable</Nullable> | ||
|
|
||
| <IsTestProject>true</IsTestProject> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="coverlet.collector" Version="6.0.2" /> | ||
| <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" /> | ||
| <PackageReference Include="NUnit" Version="4.2.2" /> | ||
| <PackageReference Include="NUnit.Analyzers" Version="4.4.0" /> | ||
| <PackageReference Include="NUnit3TestAdapter" Version="4.6.0" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <Using Include="NUnit.Framework" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <ProjectReference Include="../Functions/Functions.csproj"/> | ||
| </ItemGroup> | ||
|
|
||
| </Project> | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| // <copyright file="FunctionsTests.cs" company="Ilya Krivtsov"> | ||
| // Copyright (c) Ilya Krivtsov. All rights reserved. | ||
| // </copyright> | ||
|
|
||
| namespace Functions.Tests; | ||
|
|
||
| public class FunctionsTests | ||
| { | ||
| private static readonly IEnumerable<int> NumberSequence = Enumerable.Range(0, 120); | ||
|
|
||
| [Test] | ||
| public void Map_ConvertsNumbersToString_SameAs_Select() | ||
| { | ||
| AssertMapBehavesSameAsSelect(NumberSequence, x => x.ToString()); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Map_ConvertsStringToNumbers_SameAs_Select() | ||
| { | ||
| AssertMapBehavesSameAsSelect(NumberSequence.Select(x => x.ToString()), int.Parse); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Filter_SelectsNumbers_SameAs_Where() | ||
| { | ||
| AssertFilerBehavesSameAsWhere(NumberSequence, x => x % 2 == 0); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Filter_SelectsStrings_SameAs_Where() | ||
| { | ||
| AssertFilerBehavesSameAsWhere(NumberSequence.Select(x => x.ToString()), x => x.Contains('4')); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Fold_SumsNumbers_SameAsAggregate() | ||
| { | ||
| static int Sum(int x, int y) => x + y; | ||
|
|
||
| var aggregateResult = NumberSequence.Aggregate(Sum); | ||
| var foldResult = NumberSequence.Fold(Sum); | ||
|
|
||
| Assert.That(aggregateResult, Is.EqualTo(foldResult)); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Fold_AddsCharacters_SameAsAggregate() | ||
| { | ||
| static string Sum(string x, char y) => x + y; | ||
|
|
||
| var source = Enumerable.Range('0', '~' - '0').Select(x => (char)x); | ||
|
|
||
| var aggregateResult = source.Aggregate(string.Empty, Sum); | ||
| var foldResult = source.Fold(string.Empty, Sum); | ||
|
|
||
| Assert.That(aggregateResult, Is.EqualTo(foldResult)); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Fold_AddsCharactersAndReverses_SameAsAggregate() | ||
| { | ||
| static string Sum(string x, char y) => x + y; | ||
| static string Reverse(string s) => string.Concat(s.Reverse()); | ||
|
|
||
| var source = Enumerable.Range('0', '~' - '0').Select(x => (char)x); | ||
|
|
||
| var aggregateResult = source.Aggregate(string.Empty, Sum, Reverse); | ||
| var foldResult = source.Fold(string.Empty, Sum, Reverse); | ||
|
|
||
| Assert.That(aggregateResult, Is.EqualTo(foldResult)); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Fold_Throws_OnEmptyCollection() | ||
| { | ||
| Assert.Throws<InvalidOperationException>(() => Enumerable.Range(0, 0).Fold((x, y) => x + y)); | ||
| } | ||
|
|
||
| private static void AssertMapBehavesSameAsSelect<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, TResult> map) | ||
| { | ||
| var selectResult = source.Select(map); | ||
| var mapResult = source.Map(map); | ||
|
|
||
| Assert.That(selectResult.SequenceEqual(mapResult), Is.True); | ||
| } | ||
|
|
||
| private static void AssertFilerBehavesSameAsWhere<T>(IEnumerable<T> source, Func<T, bool> filter) | ||
| { | ||
| var whereResult = source.Where(filter); | ||
| var filterResult = source.Filter(filter); | ||
|
|
||
| Assert.That(whereResult.SequenceEqual(filterResult), Is.True); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| // <copyright file="GlobalSuppressions.cs" company="Ilya Krivtsov"> | ||
| // Copyright (c) Ilya Krivtsov. All rights reserved. | ||
| // </copyright> | ||
|
|
||
| // This file is used by Code Analysis to maintain SuppressMessage | ||
| // attributes that are applied to this project. | ||
| // Project-level suppressions either have no target or are given | ||
| // a specific target and scoped to a namespace, type, member, etc. | ||
| using System.Diagnostics.CodeAnalysis; | ||
|
|
||
| [assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "This is tests project")] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| | ||
| Microsoft Visual Studio Solution File, Format Version 12.00 | ||
| # Visual Studio Version 17 | ||
| VisualStudioVersion = 17.0.31903.59 | ||
| MinimumVisualStudioVersion = 10.0.40219.1 | ||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Functions", "Functions\Functions.csproj", "{E71A4E78-9D6C-4616-9F99-3B067B9B92F3}" | ||
| EndProject | ||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Functions.Tests", "Functions.Tests\Functions.Tests.csproj", "{D1AAD59B-65F4-4F94-B960-24C9DE9C1BB8}" | ||
| EndProject | ||
| Global | ||
| GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
| Debug|Any CPU = Debug|Any CPU | ||
| Release|Any CPU = Release|Any CPU | ||
| EndGlobalSection | ||
| GlobalSection(SolutionProperties) = preSolution | ||
| HideSolutionNode = FALSE | ||
| EndGlobalSection | ||
| GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
| {E71A4E78-9D6C-4616-9F99-3B067B9B92F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
| {E71A4E78-9D6C-4616-9F99-3B067B9B92F3}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
| {E71A4E78-9D6C-4616-9F99-3B067B9B92F3}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
| {E71A4E78-9D6C-4616-9F99-3B067B9B92F3}.Release|Any CPU.Build.0 = Release|Any CPU | ||
| {D1AAD59B-65F4-4F94-B960-24C9DE9C1BB8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
| {D1AAD59B-65F4-4F94-B960-24C9DE9C1BB8}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
| {D1AAD59B-65F4-4F94-B960-24C9DE9C1BB8}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
| {D1AAD59B-65F4-4F94-B960-24C9DE9C1BB8}.Release|Any CPU.Build.0 = Release|Any CPU | ||
| EndGlobalSection | ||
| EndGlobal |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| // <copyright file="Functions.cs" company="Ilya Krivtsov"> | ||
| // Copyright (c) Ilya Krivtsov. All rights reserved. | ||
| // </copyright> | ||
|
|
||
| namespace Functions; | ||
|
|
||
| /// <summary> | ||
| /// Utility class that contains Map, Filter and Fold functions. | ||
| /// </summary> | ||
| public static class Functions | ||
| { | ||
| /// <summary> | ||
| /// Maps all elements from <paramref name="source"/> to elements of type <typeparamref name="TResult"/> using <paramref name="map"/> function. | ||
| /// </summary> | ||
| /// <typeparam name="TSource">Source type.</typeparam> | ||
| /// <typeparam name="TResult">Type to map to.</typeparam> | ||
| /// <param name="source">Source to map.</param> | ||
| /// <param name="map">Function that maps <typeparamref name="TSource"/> to <typeparamref name="TResult"/>.</param> | ||
| /// <returns>Sequence of mapped elements.</returns> | ||
| public static IEnumerable<TResult> Map<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> map) | ||
| { | ||
| foreach (var item in source) | ||
| { | ||
| yield return map(item); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Filters elements from <paramref name="source"/> that satisfy <paramref name="predicate"/>. | ||
| /// </summary> | ||
| /// <typeparam name="T">Type of elements.</typeparam> | ||
| /// <param name="source">Source to filter.</param> | ||
| /// <param name="predicate">Function that filters elements; if it returns <see langword="true"/>, adds element to the result, otherwise, doesn't.</param> | ||
| /// <returns>Sequence of filtered elements.</returns> | ||
| public static IEnumerable<T> Filter<T>(this IEnumerable<T> source, Func<T, bool> predicate) | ||
| { | ||
| foreach (var item in source) | ||
| { | ||
| if (predicate(item)) | ||
| { | ||
| yield return item; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Folds all elements in <paramref name="source"/> into one element. | ||
| /// </summary> | ||
| /// <typeparam name="T">Type of elements.</typeparam> | ||
| /// <param name="source">Source to fold.</param> | ||
| /// <param name="folder">Function that is used to accumulate result.</param> | ||
| /// <returns>Accumulated value.</returns> | ||
| /// <exception cref="InvalidOperationException">Sequence is empty.</exception> | ||
| public static T Fold<T>(this IEnumerable<T> source, Func<T, T, T> folder) | ||
| { | ||
| var enumerator = source.GetEnumerator(); | ||
|
|
||
| if (!enumerator.MoveNext()) | ||
| { | ||
| throw new InvalidOperationException("No elements in source"); | ||
| } | ||
|
|
||
| var value = enumerator.Current; | ||
|
|
||
| while (enumerator.MoveNext()) | ||
| { | ||
| value = folder(value, enumerator.Current); | ||
| } | ||
|
|
||
| return value; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Folds all elements in <paramref name="source"/> into one element. | ||
| /// </summary> | ||
| /// <typeparam name="TSource">Type of elements in <paramref name="source"/>.</typeparam> | ||
| /// <typeparam name="TResult">The type of accumulated value.</typeparam> | ||
| /// <param name="source">Source to fold.</param> | ||
| /// <param name="initialValue">Initial value of accumulated value.</param> | ||
| /// <param name="folder">Function that is used to accumulate result.</param> | ||
| /// <returns>Accumulated value.</returns> | ||
| public static TResult Fold<TSource, TResult>(this IEnumerable<TSource> source, TResult initialValue, Func<TResult, TSource, TResult> folder) | ||
| { | ||
| var value = initialValue; | ||
| foreach (var item in source) | ||
| { | ||
| value = folder(value, item); | ||
| } | ||
|
|
||
| return value; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Folds all elements in <paramref name="source"/> into one element. | ||
| /// </summary> | ||
| /// <typeparam name="TSource">Type of elements in <paramref name="source"/>.</typeparam> | ||
| /// <typeparam name="TIntermediate">The type of accumulated value.</typeparam> | ||
| /// <typeparam name="TResult">The result type.</typeparam> | ||
| /// <param name="source">Source to fold.</param> | ||
| /// <param name="initialValue">Initial value of accumulated value.</param> | ||
| /// <param name="folder">Function that is used to accumulate result.</param> | ||
| /// <param name="map">Function that is used to convert accumulated result.</param> | ||
| /// <returns>Converted accumulated value.</returns> | ||
| public static TResult Fold<TSource, TIntermediate, TResult>(this IEnumerable<TSource> source, TIntermediate initialValue, Func<TIntermediate, TSource, TIntermediate> folder, Func<TIntermediate, TResult> map) | ||
| { | ||
| var value = initialValue; | ||
| foreach (var item in source) | ||
| { | ||
| value = folder(value, item); | ||
| } | ||
|
|
||
| return map(value); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <OutputType>Library</OutputType> | ||
| <TargetFramework>net9.0</TargetFramework> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <Nullable>enable</Nullable> | ||
| </PropertyGroup> | ||
|
|
||
| </Project> |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А где сами тесты?