Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add consume to SList #5821

Closed
wants to merge 3 commits into from

Conversation

thewilsonator
Copy link
Contributor

A range that iterates then removes elements for which the predicate is
true. An efficient combination of filter!(pred) and remove.

A range that iterates then removes elements for which the predicate is
true. An efficient combination of `filter!(pred)` and `remove`.
@dlang-bot
Copy link
Contributor

Thanks for your pull request, @thewilsonator! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.

Some tips to help speed things up:

  • smaller, focused PRs are easier to review than big ones

  • try not to mix up refactoring or style changes with bug fixes or feature enhancements

  • provide helpful commit messages explaining the rationale behind each change

Bear in mind that large or tricky changes may require multiple rounds of review and revision.

Please see CONTRIBUTING.md for more information.

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

to avoid `template instance consume!((e) => e < 0) cannot use local
'__lambda1' as parameter to non-global template consume(alias pred)()`
errors.
@edi33416
Copy link
Contributor

edi33416 commented Nov 1, 2017

This is a good idea, but we could achieve the desired behaviour by using std.algorithm.iteration.each

One could do something like this:

	auto a = SList!int(-1, 1, -2, 1, -3, 4);
	SList!int acc;
	each!((int e) => (e > 0) ? acc.insert(e) : 0)(a[]);

I believe that consume should return a SList rather than a different type.

@andralex

@thewilsonator
Copy link
Contributor Author

That works but creates a new list (with allocations and copying of data), rather than mutate the old (reference semantics). The whole point is to amortise theO(n) iteration and provide an efficient way to remove based on a predicate.

Perhaps it would be more aptly named removeYield.

@wilzbach
Copy link
Member

One could do something like this:

If you already create a new List, you can simply use filter, e.g.:

auto a = SList!int(-1, 1, -2, 1, -3, 4);
auto acc = a[].filter!(x => x > 0).SList!int;
acc.array.writeln;

Perhaps it would be more aptly named removeYield.

Yes, but the word yield isn't very common in D as everything is a range. removePred or remove might be better.

The whole point is to amortise theO(n) iteration and provide an efficient way to remove based on a predicate.

I get your point, but I'm not fully convinced that this is a popular operation, especially considering that std.container will hopefully get replaced / deprecated soonish. What do other people think?
CC @ZombineDev @JackStouffer

@JackStouffer
Copy link
Member

This seems like a lot of code for a very specific problem. What's the use case?

@andralex
Copy link
Member

This is a difficult and subtle API, though I see its necessity.

A tricky problem with SList is that removal primitives need to access the node just before the element being removed. I think the right approach is along the lines of linearRemoveElement. Currently the function takes a value and returns bool. A more composable version would return a range positioned just before the removed element. Then successive calls to linearRemoveElement would remove as many as needed, one at a time.

Then a predicated version of the function would remove by predicate, not a specific value.

@thewilsonator
Copy link
Contributor Author

I like that idea much better. Will work on it tomorrow.

@edi33416
Copy link
Contributor

edi33416 commented Feb 6, 2018

friendly ping @thewilsonator. Any updates on this?

@thewilsonator
Copy link
Contributor Author

Heh, completely forgot about it. It looks like removeLinearElement was added, but takes a value only not a predicate.

@edi33416
Copy link
Contributor

edi33416 commented Feb 6, 2018

How about adding an overload that takes a predicate? I think that's what @andralex was suggesting

@LightBender
Copy link
Contributor

PR closed as stalled. If you wish to resurrect it you are welcome to do so.

@thewilsonator thewilsonator deleted the list-consume-each branch October 26, 2024 23:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants