Skip to content

Commit

Permalink
Cleanup of nuspec files
Browse files Browse the repository at this point in the history
Added new extensions for Enumerables and Lists (moved from the Core project)
Added new unit test cases
Updated README.md
Removed unnecessary files
Updated build automation script to latest version
  • Loading branch information
ravensorb committed Sep 27, 2018
1 parent c14bed2 commit 6125f2f
Show file tree
Hide file tree
Showing 14 changed files with 539 additions and 48 deletions.
9 changes: 6 additions & 3 deletions Invisionware.Collections.sln
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".misc", ".misc", "{B67DBE97-2A64-4E27-8878-698FC381DABD}"
ProjectSection(SolutionItems) = preProject
build.cake = build.cake
build.settings.json = build.settings.json
build.version.json = build.version.json
README.md = README.md
settings.json = settings.json
version.json = version.json
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{FC9A0D21-3049-40EF-B6F1-55DA2CB685F3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Invisionware.Collections", "src\Invisionware.Collections\Invisionware.Collections.csproj", "{C6677D99-FA98-4F79-92E8-8247C54561F1}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Invisionware.Collections", "src\Invisionware.Collections\Invisionware.Collections.csproj", "{C6677D99-FA98-4F79-92E8-8247C54561F1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Invisionware.Collections.Tests", "tests\Invisionware.Collections.Tests\Invisionware.Collections.Tests.csproj", "{913CA724-9FBC-49E4-991D-D9319B74DA05}"
EndProject
Expand Down Expand Up @@ -80,4 +80,7 @@ Global
{C6677D99-FA98-4F79-92E8-8247C54561F1} = {030783D5-8B49-446B-B4BD-623CE9C87C7E}
{913CA724-9FBC-49E4-991D-D9319B74DA05} = {FC9A0D21-3049-40EF-B6F1-55DA2CB685F3}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FF83FC45-8BF9-4415-B5D5-7B2FA722C55A}
EndGlobalSection
EndGlobal
46 changes: 46 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,49 @@ dct.RenameKey("a", "key");
Console.WriteLine(dct.Keys); // Outputs key, b
```

## IEnumerable
The follow extensions are supported on IEnumerable and IEnumerable<T>

### AnySafe
This extension mimics the Any() method with the addition of being safe to all on null objects. In the event that the collection is NULL it returns FALSE

```
IList<string> lst = null;
Console.WriteLine(lst.AnySafe()); // Outputs "False"
```

### ForEach
Allows for executing a lambda expression on each object in a collection. Supports both standard and Async type methods

```
var lst = new[] { 1, 2, 3, 4 }l
var total = 0;
lst.ForEach( x => { total += x });
lst.ForEach(myCustomFunction);
```

### AddRange

### RemoveDuplicates
Allows for removing duplicate values in a collection effeciently

```
var lst = new[] { 1, 2, 1, 5, 2, 4, 6 }
var lstNew = lst.RemoveDuplicates();
```

### ToObservableCollection
Converts a collection to an Observable Collection. Useful for data binding scenerios

## List

### RemoveRange
Removes a specific number of items from the list starting at the specified location

```
var lst = new[] { 1, 2, 1, 5, 2, 4, 6 }
var result = lst.RemoveRange(2, 2); // Removes "2, 1" from the list
```
2 changes: 1 addition & 1 deletion build.version.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"Major":1,"Minor":1,"Build":5,"PreRelease":0,"ReleaseNotes":null,"Semantic":null,"Milestone":null,"CakeVersion":"0.27.2.0","IsPreRelease":false}
{"Major":1,"Minor":1,"Build":7,"PreRelease":0,"ReleaseNotes":null,"Semantic":null,"Milestone":null,"CakeVersion":"0.30.0.0","IsPreRelease":false}
15 changes: 6 additions & 9 deletions nuspec/Invisionware.Collections.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,25 @@
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
<metadata>
<id>Invisionware.Collections</id>
<version>1.1.5</version>
<version>1.1.6</version>
<title>Invisionware.Collections</title>
<authors>Invisionware</authors>
<owners>Invisionware</owners>
<projectUrl>https://github.com/Invisionware/Invisionware.Collections</projectUrl>
<licenseUrl>https://raw.githubusercontent.com/Invisionware/Invisionware.Collections/master/LICENSE</licenseUrl>
<iconUrl>https://github.com/Invisionware/Invisionware.Collections/raw/master/logo.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Contains various extension methods for collections</description>
<summary>Contains various extension methods collections</summary>
<projectUrl>https://github.com/Invisionware/Collections</projectUrl>
<licenseUrl>https://raw.githubusercontent.com/Invisionware/Collections/master/LICENSE</licenseUrl>
<iconUrl>https://github.com/Invisionware/Collections/raw/master/logo.png</iconUrl>
<releaseNotes></releaseNotes>
<copyright>Copyright © 2018 Invisionware</copyright>
<language>en-US</language>
<tags>invisionware dictionary</tags>
<tags>invisionware extensions dictionary enumerable list</tags>
<dependencies>
<dependency id="Invisionware.Core" version="1.0.0" />
</dependencies>
</metadata>
<files>
<!-- Framework: PCL -->
<file src="..\src\Invisionware.Collections\bin\$Configuration$\netstandard1.1\Invisionware.Collections.dll" target="lib\portable-net45+win8+wpa81+wp8+monoandroid+monotouch+xamarinios+xamarinmac" />
<file src="..\src\Invisionware.Collections\bin\$Configuration$\netstandard1.1\Invisionware.Collections.pdb" target="lib\portable-net45+win8+wpa81+wp8+monoandroid+monotouch+xamarinios+xamarinmac" />

<!-- Framework: NetStandard1.1 -->
<file src="..\src\Invisionware.Collections\bin\$Configuration$\netstandard1.1\Invisionware.Collections.dll" target="lib\netstandard1.1" />
<file src="..\src\Invisionware.Collections\bin\$Configuration$\netstandard1.1\Invisionware.Collections.pdb" target="lib\netstandard1.1" />
Expand Down
4 changes: 2 additions & 2 deletions src/AssemblyInfo.Shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.1.5")]
//[assembly: AssemblyFileVersion("1.1.5")]
[assembly: AssemblyVersion("1.1.7")]
//[assembly: AssemblyFileVersion("1.1.7")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
Expand Down
226 changes: 226 additions & 0 deletions src/Invisionware.Collections/EnumerableExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
using System;
using System.Collections.Generic;
using System.Collections;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;

namespace Invisionware.Collections
{
public static class EnumerableExtensions
{
/// <summary>
/// A null reference safe version of Any.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="collection">The collection.</param>
/// <param name="predicate">The predicate.</param>
/// <returns><c>true</c> if the collection is not null and contains any items, <c>false</c> otherwise.</returns>
public static bool AnySafe<T>(this IEnumerable<T> collection, Func<T, bool> predicate = null)
{
return collection != null && (predicate != null ? collection.Any(predicate) : collection.Any());
}


///// <summary>
///// A Null Safe implementation of Any
///// </summary>
///// <param name="collection">The collection.</param>
///// <returns><c>true</c> if collection contains any items, <c>false</c> otherwise.</returns>
//public static bool AnySafe(this IList collection)
//{
// return collection != null && collection.Count != 0;
//}

/// <summary>
/// Iterates through the entire collection and executes the Action on each item
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="collection">The collection.</param>
/// <param name="func">The function.</param>
/// <param name="throwException">if set to <c>true</c> [throw exception].</param>
public static void ForEach<T>(this IEnumerable<T> collection, Action<T> func, bool throwException = true)
{
if (collection == null) return;
if (func == null) return;

foreach (var item in collection)
{
try
{
func(item);
}
catch
{
if (throwException) throw;
}
}
}

/// <summary>
/// Iterates through the entire collection and executes the Action on each item
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="collection">The collection.</param>
/// <param name="func">The function.</param>
public static void ForEach(this IEnumerable collection, Action<object> func, bool throwException = true)
{
if (collection == null) return;
if (func == null) return;

foreach (var item in collection)
{
try
{
func(item);
}
catch
{
if (throwException) throw;
}
}
}

/// <summary>
/// Iterates through the entire collection and executes the Func on each item
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="collection">The collection.</param>
/// <param name="func">The function.</param>
public static IEnumerable<T> ForEach<T>(this IEnumerable collection, Func<object, T> func)
{
if (collection != null && func != null)
{
foreach (var item in collection)
{
yield return func(item);
}
}
}

/// <summary>
/// for each as an asynchronous operation.
/// </summary>
/// <typeparam name="TSource">The type of the t source.</typeparam>
/// <typeparam name="TResult">The type of the t result.</typeparam>
/// <param name="source">The source.</param>
/// <param name="selector">The selector.</param>
/// <param name="maxDegreesOfParallelism">The maximum degrees of parallelism.</param>
/// <returns>Task&lt;IList&lt;TResult&gt;&gt;.</returns>
public static async Task<IList<TResult>> ForEachAsync<TSource, TResult>(this IEnumerable<TSource> source,
Func<TSource, Task<TResult>> selector, int maxDegreesOfParallelism = 4)
{
var results = new List<TResult>();

var activeTasks = new HashSet<Task<TResult>>();
foreach (var item in source)
{
activeTasks.Add(selector(item));
if (activeTasks.Count >= maxDegreesOfParallelism)
{
var completed = await Task.WhenAny(activeTasks);
activeTasks.Remove(completed);
results.Add(completed.Result);
}
}

results.AddRange(await Task.WhenAll(activeTasks));
return results;
}

/// <summary>
/// Adds the range.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="collection">The collection.</param>
/// <param name="range">The range.</param>
/// <param name="includeFunc">The comparison function used to exclude items if needed. Return true to include, False to exclude (default is true)</param>
/// <returns>ICollection&lt;T&gt;.</returns>
public static ICollection<T> AddRange<T>(this ICollection<T> collection, IEnumerable<T> range, Func<T, bool> includeFunc = null)
{
if (collection == null) return null;

foreach (var o in range)
{
if (includeFunc == null || includeFunc(o))
{
collection.Add(o);
}
}

return collection;
}

/// <summary>
/// Removes the duplicates.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TKey">The type of the t key.</typeparam>
/// <param name="collection">The collection.</param>
/// <param name="groupByFunc">The group by function.</param>
/// <returns>ICollection&lt;T&gt;.</returns>
public static ICollection<T> RemoveDuplicates<T, TKey>(this ICollection<T> collection, Func<T, TKey> groupByFunc)
{
if (collection == null) return null;

var result = collection.Select(x => x)
.GroupBy(groupByFunc)
.Select(grp => grp.FirstOrDefault());

return result.ToObservableCollection();
}

/// <summary>
/// To the observable collection.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source">The source.</param>
/// <returns>ObservableCollection&lt;T&gt;.</returns>
public static ObservableCollection<T> ToObservableCollection<T>(this IEnumerable<T> source)
{
if (source == null) return null;

return new ObservableCollection<T>(source);
}

/// <summary>
/// Breaks the array up into Chunks of a specific size.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source">The source.</param>
/// <param name="chunkSize">Size of the chunk.</param>
/// <returns>A collection of collections that is split into slices</returns>
public static IEnumerable<IEnumerable<T>> ChunkBy<T>(this IEnumerable<T> source, int chunkSize)
{
return source
.Select((x, i) => new { Index = i, Value = x })
.GroupBy(x => x.Index / chunkSize)
.Select(x => x.Select(v => v.Value));
}

/// <summary>
/// A null reference safe version of Count.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="collection">The collection.</param>
/// <param name="predicate">The predicate.</param>
/// <returns>the number of items in the collection or 0 if its null.</returns>
public static int CountSafe<T>(this IEnumerable<T> collection, Func<T, bool> predicate = null)
{
return collection != null ? (predicate != null ? collection.Count(predicate) : collection.Count()) : 0;
}

/// <summary>
/// Takes the last n number of items in the array.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source">The source.</param>
/// <param name="count">The count.</param>
/// <returns>a new collection that contains only the last count number of items</returns>
public static IEnumerable<T> TakeLast<T>(this IEnumerable<T> source, int count)
{
return source?.Skip(Math.Max(0, source.Count() - count));
}

}
}
3 changes: 0 additions & 3 deletions src/Invisionware.Collections/FodyWeavers.xml

This file was deleted.

Loading

0 comments on commit 6125f2f

Please sign in to comment.