From 0968edab8000826a70e7b171a530267fb44bf7ad Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Sat, 1 Aug 2020 20:31:11 +0200 Subject: [PATCH] Added possibilities to use IEnumerable and ICollection to create an array. Closes: https://code.tsommer.org/thorsten/ExaArray/issues/1 https://code.tsommer.org/thorsten/ExaArray/issues/3 https://code.tsommer.org/thorsten/ExaArray/issues/4 --- ExaArray/ExaArray1D.Factories.cs | 77 ++++++++++++++++++++++ ExaArray/Extensions.Framework.cs | 50 +++++++++++++++ ExaArrayTests/ExaArray1DTests.cs | 106 +++++++++++++++++++++++++++++++ 3 files changed, 233 insertions(+) create mode 100644 ExaArray/Extensions.Framework.cs diff --git a/ExaArray/ExaArray1D.Factories.cs b/ExaArray/ExaArray1D.Factories.cs index b487aa9..9a5fb73 100644 --- a/ExaArray/ExaArray1D.Factories.cs +++ b/ExaArray/ExaArray1D.Factories.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace Exa { @@ -184,5 +185,81 @@ namespace Exa } while (leftOverTotal > 0); return next; } + + /// + /// Creates a new ExaArray1D from an enumerable sequence of items. The number of items in the sequence is __unknown__. + /// + /// + /// This factory method is slow because the number of items in the sequence is unknown. When you know the + /// number of items, you should use another factory method, where the number of items can be provided. + /// + /// Performance: O(n) + /// + /// The sequence to consume in order to create the array. + /// The optional optimization strategy. + /// The desired instance + public static ExaArray1D CreateFrom(IEnumerable sequence, Strategy strategy = Strategy.MAX_PERFORMANCE) + { + var inst = new ExaArray1D(strategy); + ulong position = 0; + foreach (var element in sequence) + { + inst.Extend(); + inst[position++] = element; + } + + return inst; + } + + /// + /// Creates a new ExaArray1D from an enumerable sequence of items. The number of items in the sequence is __known__. + /// + /// + /// Creates an array with length items. When the sequence contains less elements, the remaining values are default(T). + /// When the sequence contains more elements, these additional elements getting ignored. + /// + /// Performance: O(n) + /// + /// The sequence to consume in order to create the array. + /// The number of elements in the sequence. When the sequence contains more elements, these additional elements are ignored. + /// The optional optimization strategy. + /// The desired instance + public static ExaArray1D CreateFrom(IEnumerable sequence, ulong length, Strategy strategy = Strategy.MAX_PERFORMANCE) + { + var inst = new ExaArray1D(strategy); + inst.Extend(length); + + ulong position = 0; + foreach (var element in sequence) + { + if(position == length) + break; + + inst[position++] = element; + } + + return inst; + } + + /// + /// Creates a new ExaArray1D from a collection of items. + /// + /// + /// Performance: O(n) + /// + /// The collection to use + /// The optional optimization strategy. + /// The desired instance + public static ExaArray1D CreateFrom(ICollection collection, Strategy strategy = Strategy.MAX_PERFORMANCE) + { + var inst = new ExaArray1D(strategy); + inst.Extend((ulong) collection.Count); + + ulong position = 0; + foreach (var element in collection) + inst[position++] = element; + + return inst; + } } } \ No newline at end of file diff --git a/ExaArray/Extensions.Framework.cs b/ExaArray/Extensions.Framework.cs new file mode 100644 index 0000000..8e48e83 --- /dev/null +++ b/ExaArray/Extensions.Framework.cs @@ -0,0 +1,50 @@ +using System.Collections.Generic; + +namespace Exa +{ + /// + /// Contains extension methods. + /// + public static class ExtensionsFramework + { + /// + /// Creates a new ExaArray1D from this collection of items. + /// + /// + /// Performance: O(n) + /// + /// The collection to use + /// The optional optimization strategy. + /// The desired instance + public static ExaArray1D AsExaArray(this ICollection collection, Strategy strategy = Strategy.MAX_PERFORMANCE) => ExaArray1D.CreateFrom(collection, strategy); + + /// + /// Creates a new ExaArray1D from this enumerable sequence of items. The number of items in the sequence is __known__. + /// + /// + /// Creates an array with length items. When this sequence contains less elements, the remaining values are default(T). + /// When the sequence contains more elements, these additional elements getting ignored. + /// + /// Performance: O(n) + /// + /// The sequence to consume in order to create the array. + /// The number of elements in the sequence. When the sequence contains more elements, these additional elements are ignored. + /// The optional optimization strategy. + /// The desired instance + public static ExaArray1D AsExaArray(this IEnumerable sequence, ulong length, Strategy strategy = Strategy.MAX_PERFORMANCE) => ExaArray1D.CreateFrom(sequence, length, strategy); + + /// + /// Creates a new ExaArray1D from this enumerable sequence of items. The number of items in the sequence is __unknown__. + /// + /// + /// This method is slow because the number of items in this sequence is unknown. When you know the + /// number of items, you should use another factory method, where the number of items can be provided. + /// + /// Performance: O(n) + /// + /// The sequence to consume in order to create the array. + /// The optional optimization strategy. + /// The desired instance + public static ExaArray1D AsExaArray(this IEnumerable sequence, Strategy strategy = Strategy.MAX_PERFORMANCE) => ExaArray1D.CreateFrom(sequence, strategy); + } +} \ No newline at end of file diff --git a/ExaArrayTests/ExaArray1DTests.cs b/ExaArrayTests/ExaArray1DTests.cs index dc69630..084661b 100644 --- a/ExaArrayTests/ExaArray1DTests.cs +++ b/ExaArrayTests/ExaArray1DTests.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; @@ -549,6 +550,111 @@ namespace ExaArrayTests Assert.That(next3.Length, Is.EqualTo(exPerf.Length)); Assert.That(next4.Length, Is.EqualTo(exPerf.Length)); } + + [Test] + [Category("normal")] + [Category("cover")] + public void CreateFromSequence001() + { + var list = new List + { + 5, + 7, + 8, + 10, + 16, + }; + + var exPerf1 = list.AsExaArray(); + Assert.That(exPerf1.OptimizationStrategy, Is.EqualTo(Strategy.MAX_PERFORMANCE)); + Assert.That(exPerf1.Length, Is.EqualTo(list.Count)); + Assert.That(exPerf1.Items(), Is.EquivalentTo(list)); + + var exPerf2 = list.AsExaArray(Strategy.MAX_ELEMENTS); + Assert.That(exPerf2.OptimizationStrategy, Is.EqualTo(Strategy.MAX_ELEMENTS)); + Assert.That(exPerf2.Length, Is.EqualTo(list.Count)); + Assert.That(exPerf2.Items(), Is.EquivalentTo(list)); + } + + [Test] + [Category("normal")] + [Category("cover")] + public void CreateFromSequence002() + { + var array = new int[] + { + 5, + 7, + 8, + 10, + 16, + }; + + var exPerf1 = array.AsExaArray(); + Assert.That(exPerf1.OptimizationStrategy, Is.EqualTo(Strategy.MAX_PERFORMANCE)); + Assert.That(exPerf1.Length, Is.EqualTo(array.Length)); + Assert.That(exPerf1.Items(), Is.EquivalentTo(array)); + + var exPerf2 = array.AsExaArray(Strategy.MAX_ELEMENTS); + Assert.That(exPerf2.OptimizationStrategy, Is.EqualTo(Strategy.MAX_ELEMENTS)); + Assert.That(exPerf2.Length, Is.EqualTo(array.Length)); + Assert.That(exPerf2.Items(), Is.EquivalentTo(array)); + } + + [Test] + [Category("normal")] + [Category("cover")] + public void CreateFromSequence003() + { + var list = new List + { + 5, + 7, + 8, + 10, + 16, + }; + + var exPerf1 = list.AsEnumerable().AsExaArray(); + Assert.That(exPerf1.OptimizationStrategy, Is.EqualTo(Strategy.MAX_PERFORMANCE)); + Assert.That(exPerf1.Length, Is.EqualTo(list.Count)); + Assert.That(exPerf1.Items(), Is.EquivalentTo(list)); + + var exPerf2 = list.AsEnumerable().AsExaArray(Strategy.MAX_ELEMENTS); + Assert.That(exPerf2.OptimizationStrategy, Is.EqualTo(Strategy.MAX_ELEMENTS)); + Assert.That(exPerf2.Length, Is.EqualTo(list.Count)); + Assert.That(exPerf2.Items(), Is.EquivalentTo(list)); + } + + [Test] + [Category("normal")] + [Category("cover")] + public void CreateFromSequence004() + { + var list = new List + { + 5, + 7, + 8, + 10, + 16, + }; + + var exPerf1 = list.AsEnumerable().AsExaArray((ulong) list.Count); + Assert.That(exPerf1.OptimizationStrategy, Is.EqualTo(Strategy.MAX_PERFORMANCE)); + Assert.That(exPerf1.Length, Is.EqualTo(list.Count)); + Assert.That(exPerf1.Items(), Is.EquivalentTo(list)); + + var exPerf2 = list.AsEnumerable().AsExaArray((ulong) list.Count, Strategy.MAX_ELEMENTS); + Assert.That(exPerf2.OptimizationStrategy, Is.EqualTo(Strategy.MAX_ELEMENTS)); + Assert.That(exPerf2.Length, Is.EqualTo(list.Count)); + Assert.That(exPerf2.Items(), Is.EquivalentTo(list)); + + var exPerf3 = list.AsEnumerable().AsExaArray(3); + Assert.That(exPerf3.OptimizationStrategy, Is.EqualTo(Strategy.MAX_PERFORMANCE)); + Assert.That(exPerf3.Length, Is.EqualTo(3)); + Assert.That(exPerf3.Items(), Is.EquivalentTo(new int[] {5,7,8})); + } [Test] [Category("intensive")]