C
C#2y ago
Thinker

Replace element in immutable array matching predicate [Answered]

Got a simple issue, I want to replace an element in an ImmutableArray<T> which matches a predicate with another item. Is there some handy Linq method which could do this easily or am I just gonna have to write my own?
17 Replies
Doombox
Doombox2y ago
forgive the ignorance, but doesn't that kind of defeat the purpose of an immutable array?
Thinker
Thinker2y ago
I say "replace an item" when I really mean "return a new immutable array with the item replaced"
Doombox
Doombox2y ago
I guess you'd just have to create your own ToImmutableArray() extension other than that just use regular LINQ to exclude the item then pass it into a new ImmutableArray.Create<T>(immutable.Where(x => x != y).ToArray()) the extension method would basically be the same deal oh you want to replace that specific item, not remove it, i can't read then yeah LINQ doesn't have a replace out of the box,, so you'd have to write that too
MODiX
MODiX2y ago
thinker227#5176
REPL Result: Success
record Person(string Name, int Age);
static IEnumerable<T> ReplaceElement<T>(this IEnumerable<T> source, Func<T, bool> predicate, T item)
{
foreach (var x in source)
{
if (predicate(x)) yield return item;
else yield return x;
}
}

var people = new Person[] {new("Rick Astley", 53), new("Michael Stevens", 36)};
people.ReplaceElement(p => p.Age > 50, new("Joe Biden", 79))
record Person(string Name, int Age);
static IEnumerable<T> ReplaceElement<T>(this IEnumerable<T> source, Func<T, bool> predicate, T item)
{
foreach (var x in source)
{
if (predicate(x)) yield return item;
else yield return x;
}
}

var people = new Person[] {new("Rick Astley", 53), new("Michael Stevens", 36)};
people.ReplaceElement(p => p.Age > 50, new("Joe Biden", 79))
Result: <ReplaceElement>d__2<Person>
[
{
"name": "Joe Biden",
"age": 79
},
{
"name": "Michael Stevens",
"age": 36
}
]
[
{
"name": "Joe Biden",
"age": 79
},
{
"name": "Michael Stevens",
"age": 36
}
]
Compile: 724.712ms | Execution: 174.702ms | React with ❌ to remove this embed.
Thinker
Thinker2y ago
yeah that works
Doombox
Doombox2y ago
implement ToImmutableArray() and ReplaceElement and you're golden
Thinker
Thinker2y ago
ToImmutableArray() already exists catsip
Doombox
Doombox2y ago
does it? then even less work sunglas implemented my own immutable collections if I needed them, first time I'm hearing of an immutable collections namespace and nuget package
MODiX
MODiX2y ago
thinker227#5176
REPL Result: Success
using System.Collections.Immutable;
new[] {1,2,3,4,5}.ToImmutableArray()
using System.Collections.Immutable;
new[] {1,2,3,4,5}.ToImmutableArray()
Result: ImmutableArray<int>
[
1,
2,
3,
4,
5
]
[
1,
2,
3,
4,
5
]
Compile: 470.805ms | Execution: 41.198ms | React with ❌ to remove this embed.
Doombox
Doombox2y ago
feel like a bit of a catclown now
Thinker
Thinker2y ago
It's actually just part of the standard library now. I use ImmutableArray<T> pretty often since it's really useful (and optimized).
Doombox
Doombox2y ago
ah, I haven't needed one in quite a while, so probably not that much of a clown
Thinker
Thinker2y ago
Nah, depends a lot on what you're doing
Doombox
Doombox2y ago
I think I needed one a couple years ago and literally just copy pasted an existing implementation I had so if it was around then I didn't even check
Thinker
Thinker2y ago
If you're a masochist like me and really like functional patterns then immutability is a necessity catsip
Doombox
Doombox2y ago
mostly do immutability through exposing IReadOnly collections really but that's only technically immutable well I guess so are the immutable collections if you try hard enough
Accord
Accord2y ago
✅ This post has been marked as answered!