Bug 10930 – std.array.replace cannot simple replace an element in array

Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-08-30T12:39:26Z
Last change time
2018-11-15T07:20:38Z
Keywords
pull
Assigned to
No Owner
Creator
Temtaime

Comments

Comment #0 by temtaime — 2013-08-30T12:39:26Z
That should be accepted: auto arr = [ 1, 1, 1 ]; arr = replace(arr, 1, 2); writeln(arr);
Comment #1 by safety0ff.bugz — 2014-06-13T20:38:14Z
See also: issue #12890
Comment #2 by safety0ff.bugz — 2014-06-13T20:40:06Z
Also, replaceInPlace and replaceSlice are better candidates for this type of operation.
Comment #3 by razvan.nitu1305 — 2017-08-31T09:46:55Z
This should do the trick: auto arr = [ 1, 1, 1 ]; arr = replace(arr, 1, 2); writeln(arr); I suggest we close this.
Comment #4 by razvan.nitu1305 — 2017-08-31T09:47:54Z
This should do the trick: auto arr = [ 1, 1, 1 ]; replaceInPlace(arr, 1, 2, [2]); writeln(arr); I suggest we close this. Sorry for the above comment. It was a copy-paste mistake.
Comment #5 by petar.p.kirov — 2017-08-31T10:52:15Z
The main issue with `replaceInPlace(arr, 1, 2, [2])` is that: 1. The simple usage requires a dynamic allocation for the `[2]` array. The user could use a separate static array and pass a slice to it, or use `only(2)`, but it's not convenient for such simple use case 2. A `replaceInPlace` overload takes a single element, instead of a range can be made much faster by using specialized SIMD instructions, which is worth considering
Comment #6 by temtaime — 2017-09-01T19:30:12Z
I don't see a reason why single element cannot be replaced For example, both this examples works: [1, 2].split([1]); [1, 2].split(1);
Comment #7 by greensunny12 — 2018-01-09T17:42:14Z
This applied on top of https://github.com/dlang/phobos/pull/6017 will make it work: diff --git a/std/array.d b/std/array.d index 3a44612cb..207b1280d 100644 --- a/std/array.d +++ b/std/array.d @@ -2120,21 +2120,21 @@ if (isInputRange!RoR && $(REF map, std,algorithm,iteration) which can act as a lazy replace +/ E[] replace(E, R1, R2)(E[] subject, R1 from, R2 to) -if (isDynamicArray!(E[]) && isForwardRange!R1 && isForwardRange!R2 - && (hasLength!R2 || isSomeString!R2)) +if (isDynamicArray!(E[])) { import std.algorithm.searching : find; import std.range : dropOne; - if (from.empty) return subject; + static if (isInputRange!R1) + if (from.empty) return subject; - auto balance = find(subject, from.save); + auto balance = find(subject, from); if (balance.empty) return subject; auto app = appender!(E[])(); app.put(subject[0 .. subject.length - balance.length]); - app.put(to.save); + app.put(to); // replacing an element in an array is different to a range replacement static if (is(Unqual!E : Unqual!R1)) replaceInto(app, balance.dropOne, from, to); @@ -2158,6 +2158,11 @@ if (isDynamicArray!(E[]) && isForwardRange!R1 && isForwardRange!R2 assert([3, 3, 4, 3].replace([3, 3], [1, 1, 1]) == [1, 1, 1, 4, 3]); } +@safe unittest +{ + assert([0, 1, 2].replace(1, 4) == [0, 4, 2]); +} + // https://issues.dlang.org/show_bug.cgi?id=18215 @safe unittest { @@ -2181,28 +2186,29 @@ if (isDynamicArray!(E[]) && isForwardRange!R1 && isForwardRange!R2 /// ditto void replaceInto(E, Sink, R1, R2)(Sink sink, E[] subject, R1 from, R2 to) -if (isOutputRange!(Sink, E) && isDynamicArray!(E[]) - && isForwardRange!R1 && isForwardRange!R2 - && (hasLength!R2 || isSomeString!R2)) +if (isOutputRange!(Sink, E) && isDynamicArray!(E[])) { import std.algorithm.searching : find; import std.range : dropOne; - if (from.empty) + static if (isInputRange!R1) { - sink.put(subject); - return; + if (from.empty) + { + sink.put(subject); + return; + } } for (;;) { - auto balance = find(subject, from.save); + auto balance = find(subject, from); if (balance.empty) { sink.put(subject); break; } sink.put(subject[0 .. subject.length - balance.length]); - sink.put(to.save); + sink.put(to); // replacing an element in an array is different to a range replacement static if (is(Unqual!E : Unqual!R1)) subject = balance.dropOne; Of course constraints need be set, but to be fair currently there aren't any for this
Comment #8 by greensunny12 — 2018-01-09T21:43:30Z
Comment #9 by github-bugzilla — 2018-11-15T07:20:37Z
Commits pushed to master at https://github.com/dlang/phobos https://github.com/dlang/phobos/commit/bf5dc02f1a898e5283bbd8edfc60b03887f1f47c Fix Issue 9702, 10930 - std.array.replace cannot simple replace an element in array https://github.com/dlang/phobos/commit/ce6d6cadb728a656749e8b0a04b2c5ac88b50c80 Merge pull request #6022 from wilzbach/fix-10930 Fix Issue 10930 - std.array.replace cannot simple replace an element in array