Bug 13903 – std.array.removeIf for associative arrays

Status
NEW
Severity
enhancement
Priority
P4
Component
phobos
Product
D
Version
D2
Platform
x86
OS
Windows
Creation time
2014-12-28T01:02:32Z
Last change time
2024-12-01T16:23:27Z
Assigned to
No Owner
Creator
bearophile_hugs
Moved to GitHub: phobos#10108 →

Comments

Comment #0 by bearophile_hugs — 2014-12-28T01:02:32Z
A pattern in D code is to remove key-value pairs from an associative array according to some given rule. This pattern: - Is sufficiently common in D code; - It's bug prone because iterating an associative array you are removing items from could cause troubles; - It can be implemented with a simple clear function; - It's often implemented not efficiently in user cose because sometimes you solve the problem copying all the associative array, with memory-wasting code like: int[int] aa = ...; foreach (key; aa.keys) if (predicate1(key)) aa.remove(key); foreach (key; aa.keys) { auto value = aa[key]; if (predicate2(key, value)) aa.remove(key); } So I suggest a function named like std.array.removeIf that accepts a predicate with one or two arguments, if the predicate has one argument it receives the key, otherwise it receives both key and value: aa.removeIf!(key => key > 5); aa.removeIf!((key, val) => key > val); (The name of the function doesn't contain "associative array" because later an overload of "removeIf" can be defined for dynamic arrays too).
Comment #1 by greensunny12 — 2018-03-31T16:27:36Z
Not sure whether such one/two-liners would be accepted to Phobos. --- import std.experimental.all; auto removeIf(alias pred, AA)(AA aa) { aa.byPair.filter!(not!pred).each!(e => aa.remove(e.key)); return aa; } void main() { auto aa = ["a" : 1, "b" : 2]; aa.removeIf!(a => a.key == "a").writeln; } --- But efficiency and bug-proneness are two good points.
Comment #2 by schveiguy — 2019-06-18T23:55:59Z
(In reply to Seb from comment #1) > auto removeIf(alias pred, AA)(AA aa) > { > aa.byPair.filter!(not!pred).each!(e => aa.remove(e.key)); > return aa; > } This implementation isn't valid. You can't remove while iterating. You would need to somehow lock the AA from rehashing as you removed items.
Comment #3 by schveiguy — 2019-06-18T23:56:28Z
I think especially if you remove the CURRENT element while iterating you are in for trouble.
Comment #4 by robert.schadek — 2024-12-01T16:23:27Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/phobos/issues/10108 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB