From 756a3e4294fcf7ee5274a7fafdf8f25d087c8d8f Mon Sep 17 00:00:00 2001 From: Matthew O'Connor Date: Tue, 5 Aug 2025 15:50:19 -0600 Subject: [PATCH 1/2] Provide ToImmArray extension methods that take a `Func select`. --- Xledger.Collections.Test/TestImmArray.cs | 11 +++++++ Xledger.Collections.Test/TestImmSet.cs | 9 ++++++ Xledger.Collections/Extensions.cs | 40 ++++++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/Xledger.Collections.Test/TestImmArray.cs b/Xledger.Collections.Test/TestImmArray.cs index 0771ac7..3c6fe71 100644 --- a/Xledger.Collections.Test/TestImmArray.cs +++ b/Xledger.Collections.Test/TestImmArray.cs @@ -172,5 +172,16 @@ public void TestSpan() { } public record Employee(int Id, string Name, decimal Salary); + + [Fact] + public void TestToImmArrayWithFunc() { + var arr = Enumerable.Range(-1, 100).Select(i => $"{i}: {2*i}").ToArray(); + var imm = Enumerable.Range(-1, 100).ToImmArray(i => $"{i}: {2 * i}"); + Assert.Equal(arr.Length, imm.Length); + Assert.Equal("-1: -2", imm[0]); + for (int i = 0; i < imm.Length; ++i) { + Assert.Equal(arr[i], imm[i]); + } + } } diff --git a/Xledger.Collections.Test/TestImmSet.cs b/Xledger.Collections.Test/TestImmSet.cs index ced1dcc..b9a360d 100644 --- a/Xledger.Collections.Test/TestImmSet.cs +++ b/Xledger.Collections.Test/TestImmSet.cs @@ -107,6 +107,15 @@ public void TestNoOps() { Assert.ThrowsAny(() => iset.Remove(4)); Assert.ThrowsAny(() => ((System.Collections.ICollection)iset).CopyTo((Array)null, 0)); } + + [Fact] + public void TestSelect() { + var imm = Enumerable.Range(-10, 21).ToImmSet(Math.Abs); + Assert.Equal(11, imm.Count); + for (int i = 0; i < 10; ++i) { + Assert.Contains(i, (ISet)imm); + } + } } diff --git a/Xledger.Collections/Extensions.cs b/Xledger.Collections/Extensions.cs index e5caab7..37414e6 100644 --- a/Xledger.Collections/Extensions.cs +++ b/Xledger.Collections/Extensions.cs @@ -12,6 +12,16 @@ public static ImmArray ToImmArray(this IEnumerable xs) { }; } + public static ImmArray ToImmArray(this IEnumerable xs, Func select) { + return xs switch { + null => ImmArray.Empty, + T[] arr => new ImmArray(ArrayOf(arr.Length, arr, select)), + ICollection coll => new ImmArray(ArrayOf(coll.Count, coll, select)), + IReadOnlyCollection roColl => new ImmArray(ArrayOf(roColl.Count, roColl, select)), + _ => new ImmArray(ArrayOf(xs, select)), + }; + } + #if NET public static ImmArray ToImmArray(this ReadOnlySpan xs) { return new ImmArray(xs.ToArray()); @@ -26,6 +36,13 @@ public static ImmSet ToImmSet(this IEnumerable xs) { }; } + public static ImmSet ToImmSet(this IEnumerable xs, Func select) { + return xs switch { + null => ImmSet.Empty, + _ => new ImmSet(SetOf(xs, select)), + }; + } + #if NET public static ImmSet ToImmSet(this ReadOnlySpan xs) { return new ImmSet(xs.ToArray()); @@ -64,6 +81,7 @@ Func selectVal _ => new ImmDict(xs.ToDictionary(selectKey, selectVal)), }; } + internal static T[] ArrayOf(T[] arr) { return (T[])arr.Clone(); } @@ -92,10 +110,32 @@ internal static T[] ArrayOf(IEnumerable xs) { return lst.ToArray(); } + internal static U[] ArrayOf(int n, IEnumerable xs, Func f) { + var arr = new U[n]; + var i = 0; + foreach (var x in xs) { + arr[i] = f(x); + ++i; + } + return arr; + } + + internal static U[] ArrayOf(IEnumerable xs, Func f) { + var lst = new List(); + foreach (var x in xs) { + lst.Add(f(x)); + } + return lst.ToArray(); + } + internal static HashSet SetOf(IEnumerable xs) { return new HashSet(xs); } + internal static HashSet SetOf(IEnumerable xs, Func f) { + return new HashSet(xs.Select(f)); + } + internal static Dictionary DictOf(IEnumerable> xs) { #if NET6_0_OR_GREATER return new Dictionary(xs, null); From 57ef7babf50a810fc880c37f238ad112917acb48 Mon Sep 17 00:00:00 2001 From: Matthew O'Connor Date: Tue, 5 Aug 2025 16:15:43 -0600 Subject: [PATCH 2/2] select -> selector --- Xledger.Collections/Extensions.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Xledger.Collections/Extensions.cs b/Xledger.Collections/Extensions.cs index 37414e6..31338bd 100644 --- a/Xledger.Collections/Extensions.cs +++ b/Xledger.Collections/Extensions.cs @@ -12,13 +12,13 @@ public static ImmArray ToImmArray(this IEnumerable xs) { }; } - public static ImmArray ToImmArray(this IEnumerable xs, Func select) { + public static ImmArray ToImmArray(this IEnumerable xs, Func selector) { return xs switch { null => ImmArray.Empty, - T[] arr => new ImmArray(ArrayOf(arr.Length, arr, select)), - ICollection coll => new ImmArray(ArrayOf(coll.Count, coll, select)), - IReadOnlyCollection roColl => new ImmArray(ArrayOf(roColl.Count, roColl, select)), - _ => new ImmArray(ArrayOf(xs, select)), + T[] arr => new ImmArray(ArrayOf(arr.Length, arr, selector)), + ICollection coll => new ImmArray(ArrayOf(coll.Count, coll, selector)), + IReadOnlyCollection roColl => new ImmArray(ArrayOf(roColl.Count, roColl, selector)), + _ => new ImmArray(ArrayOf(xs, selector)), }; } @@ -36,10 +36,10 @@ public static ImmSet ToImmSet(this IEnumerable xs) { }; } - public static ImmSet ToImmSet(this IEnumerable xs, Func select) { + public static ImmSet ToImmSet(this IEnumerable xs, Func selector) { return xs switch { null => ImmSet.Empty, - _ => new ImmSet(SetOf(xs, select)), + _ => new ImmSet(SetOf(xs, selector)), }; }