delete_if, select and (lack of) delete_if!, self.POLS == false

S

Saku Ytti

Hey everyone,

I was looking today for version of Array#select that would mutate the array
by deleting selected elements from it.
I first looked at delete_if, then noticed that it actually mutates original
array and returns mutated array. I wonder would it make sense for delete_if
not to mutate and return new array and delete_if! to mutate and return deleted
elements?

Of course what I want is simple method to implement, it just seems pretty
typical desire for Array#select usage cases and also perhaps mutating
delete_if is as well bit unexpected? Problem is, suggested change would
break many current delete_if usage cases.

Thanks,
 
A

ara.t.howard

Hey everyone,

I was looking today for version of Array#select that would mutate
the array
by deleting selected elements from it.
I first looked at delete_if, then noticed that it actually mutates
original
array and returns mutated array. I wonder would it make sense for
delete_if
not to mutate and return new array and delete_if! to mutate and
return deleted
elements?

Of course what I want is simple method to implement, it just seems
pretty
typical desire for Array#select usage cases and also perhaps mutating
delete_if is as well bit unexpected? Problem is, suggested change
would
break many current delete_if usage cases.

a non-mutating delete_if is already there:

array.select{|element| not orginal_condition(element)}

ie

odds = [0,1,2,3].select{|i| not i.even?}

a @ http://codeforpeople.com/
 
D

David A. Black

Hi --

Hey everyone,

I was looking today for version of Array#select that would mutate the array
by deleting selected elements from it.
I first looked at delete_if, then noticed that it actually mutates original
array and returns mutated array. I wonder would it make sense for delete_if
not to mutate and return new array and delete_if! to mutate and return deleted
elements?

Of course what I want is simple method to implement, it just seems pretty
typical desire for Array#select usage cases and also perhaps mutating
delete_if is as well bit unexpected? Problem is, suggested change would
break many current delete_if usage cases.

You should use #reject, which is non-destructive.


David

--
Rails training from David A. Black and Ruby Power and Light:
ADVANCING WITH RAILS April 14-17 New York City
INTRO TO RAILS June 9-12 Berlin
ADVANCING WITH RAILS June 16-19 Berlin
See http://www.rubypal.com for details and updates!
 
D

David A. Black

Hi --

Hey everyone,

I was looking today for version of Array#select that would mutate the array
by deleting selected elements from it.
I first looked at delete_if, then noticed that it actually mutates original
array and returns mutated array. I wonder would it make sense for delete_if
not to mutate and return new array and delete_if! to mutate and return
deleted
elements?

Of course what I want is simple method to implement, it just seems pretty
typical desire for Array#select usage cases and also perhaps mutating
delete_if is as well bit unexpected? Problem is, suggested change would
break many current delete_if usage cases.

a non-mutating delete_if is already there:

array.select{|element| not orginal_condition(element)}

ie

odds = [0,1,2,3].select{|i| not i.even?}

Also:

odds = [0,1,2,3].reject {|i| i.even? }


David

--
Rails training from David A. Black and Ruby Power and Light:
ADVANCING WITH RAILS April 14-17 New York City
INTRO TO RAILS June 9-12 Berlin
ADVANCING WITH RAILS June 16-19 Berlin
See http://www.rubypal.com for details and updates!
 
S

Saku Ytti

On (2008-04-12 01:32 +0900), David A. Black wrote:

Thanks everyone for fast reply.
You should use #reject, which is non-destructive.

I guess I wasn't being clear, indeed reject removes the need for
non-mutating delete_if, which would make them equal. However, we're still
without method that does select, but mutates the returned elements out from
the original array.
If we'd have it, I guess select! would be bit odd name for it? And if it would
be delete_if! then mutating delete_if would be even more surprising?

Also, I may be biased with my own problem thinking that select that removes
elements from array is typical need. Just feels so at the moment.
 
R

Robert Dober

Hi --


Hey everyone,

I was looking today for version of Array#select that would mutate the array
by deleting selected elements from it.
I first looked at delete_if, then noticed that it actually mutates original
array and returns mutated array. I wonder would it make sense for delete_if
not to mutate and return new array and delete_if! to mutate and return deleted
elements?

Of course what I want is simple method to implement, it just seems pretty
typical desire for Array#select usage cases and also perhaps mutating
delete_if is as well bit unexpected? Problem is, suggested change would
break many current delete_if usage cases.

a non-mutating delete_if is already there:

array.select{|element| not orginal_condition(element)}

ie

odds = [0,1,2,3].select{|i| not i.even?}

Also:

odds = [0,1,2,3].reject {|i| i.even? }
I guess even I could come up with an odd solution. (t'is 1 funny maybe?)
R.
 
R

Robert Dober

On (2008-04-12 01:32 +0900), David A. Black wrote:

Thanks everyone for fast reply.



I guess I wasn't being clear, indeed reject removes the need for
non-mutating delete_if, which would make them equal. However, we're still
without method that does select, but mutates the returned elements out from
the original array.
If we'd have it, I guess select! would be bit odd name for it? And if it would
be delete_if! then mutating delete_if would be even more surprising?

Also, I may be biased with my own problem thinking that select that removes
elements from array is typical need. Just feels so at the moment.
No, I agree with you but OTOH not many seem to see the need for this
and the community is rather pragmatic about these things.
I would prefer to have a reject and a reject! but I am pragmatic about
democracy ;), and a large majority seems not to see the need for this.
Now I would love to stand corrected of course ;).

Cheers
Robert
 
D

David A. Black

Hi --

On (2008-04-12 01:32 +0900), David A. Black wrote:

Thanks everyone for fast reply.


I guess I wasn't being clear, indeed reject removes the need for
non-mutating delete_if, which would make them equal. However, we're still
without method that does select, but mutates the returned elements out from
the original array.
If we'd have it, I guess select! would be bit odd name for it? And if it would
be delete_if! then mutating delete_if would be even more surprising?

Also, I may be biased with my own problem thinking that select that removes
elements from array is typical need. Just feels so at the moment.

So you want a kind of #keep_if ?


David

--
Rails training from David A. Black and Ruby Power and Light:
ADVANCING WITH RAILS April 14-17 New York City
INTRO TO RAILS June 9-12 Berlin
ADVANCING WITH RAILS June 16-19 Berlin
See http://www.rubypal.com for details and updates!
 
S

Saku Ytti

No, I agree with you but OTOH not many seem to see the need for this
and the community is rather pragmatic about these things.
I would prefer to have a reject and a reject! but I am pragmatic about
democracy ;), and a large majority seems not to see the need for this.
Now I would love to stand corrected of course ;).

Hmm yeah, so you'd name them something like this?

class Array;def reject!(&blk)
reject(&blk).each{|e|delete e};end
def select!(&blk)
select(&blk).each{|e|delete e};end;end

so reject! does mutating reject and returns non-rejected
and select! does mutating select and returns non-selected.

So if I'd want the 'select' behaviour I was missing, I'd
just call reject!

Upside of this solution is, it wouldn't tinker with
anything existing. But still not sure if people commonly
want something like this.
 
S

Saku Ytti

class Array;def reject!(&blk)
reject(&blk).each{|e|delete e};end
def select!(&blk)
select(&blk).each{|e|delete e};end;end

Actually just inside out, reject! should be select(&blk)
and select! should be reject(&blk).
 
S

Saku Ytti

So you want a kind of #keep_if ?

Just to implement the previous suggestion correctly(tm) this time.

This is more or less what I want
class Array;def reject!(&blk)
select(&blk).each{|e|delete e};end
def select!(&blk)
reject(&blk).each{|e|delete e};end;end

now if I do array.reject! I actually get array mutated
but it returns the non-rejected.
So kinda destructive/mutating select.
 
R

Robert Dober

Actually just inside out, reject! should be select(&blk)
and select! should be reject(&blk).
No, not quite

x=[*0..1]
x.select{|n| n.even?} -> [0]
x -> [0,1]
x.reject!{|n| n.odd?} -> [0]
x -> [0]

Cheers
Robert
 
S

Saku Ytti

x=[*0..1]
x.select{|n| n.even?} -> [0]
x -> [0,1]
x.reject!{|n| n.odd?} -> [0]
x -> [0]

Not sure what's going on there, but this looks correct to me:

irb(main):001:0> class Array;def reject!(&blk)
irb(main):002:2> select(&blk).each{|e|delete e};end
irb(main):003:1> def select!(&blk)
irb(main):004:2> reject(&blk).each{|e|delete e};end;end
=> nil
irb(main):005:0> x=[*0..1]
=> [0, 1]
irb(main):006:0> x.select{|n| n.even?}
=> [0]
irb(main):007:0> x
=> [0, 1]
irb(main):008:0> x.reject!{|n| n.odd?}
=> [1]
irb(main):009:0> x
=> [0]
irb(main):010:0>
 
D

David A. Black

Hi --

x=[*0..1]
x.select{|n| n.even?} -> [0]
x -> [0,1]
x.reject!{|n| n.odd?} -> [0]
x -> [0]

Not sure what's going on there, but this looks correct to me:

select is selecting all the even ones, and reject! is rejecting all
the odd ones, and in both cases, you're seeing the results (the array
with only the even ones; the array without the odd ones). In the case
of reject! you're also seeing that the contents of the array have been
replaced with the results of the reject operation.

I think if you want a reject operation whose return value is the same
as a select operation, you'll probably need to come up with a new
method name :)


David

--
Rails training from David A. Black and Ruby Power and Light:
ADVANCING WITH RAILS April 14-17 New York City
INTRO TO RAILS June 9-12 Berlin
ADVANCING WITH RAILS June 16-19 Berlin
See http://www.rubypal.com for details and updates!
 
S

Saku Ytti

select is selecting all the even ones, and reject! is rejecting all
the odd ones, and in both cases, you're seeing the results (the array
with only the even ones; the array without the odd ones). In the case
of reject! you're also seeing that the contents of the array have been
replaced with the results of the reject operation.

Are you talking about your example or my example? They did different thing,
I'm not sure why your did what it did above.
I think if you want a reject operation whose return value is the same
as a select operation, you'll probably need to come up with a new
method name :)

The reject! in my example does mutable reject, as one would expect.
But it also returns the non-rejected entries (that is, those entries that
select for same block would return).

Again, I'm not sure if this as typical need for select as I think it is.
But if think of all applications where you need to split array to multiple
arrays in a way where no entry can be ever needed to put to multiple
arrays, it would be lot cheaper to reduce the array size while going
it through. Kinda like select + pop, if you want another way to think
of it.

Thanks,
 
D

David A. Black

Hi --

Are you talking about your example or my example? They did different thing,
I'm not sure why your did what it did above.


The reject! in my example does mutable reject, as one would expect.
But it also returns the non-rejected entries (that is, those entries that
select for same block would return).

Having reject return the non-rejected entries is what I was referring
to. That's not how reject (with or without !) works, so if you want a
method that does that you'd want to find a different name for it.


David

--
Rails training from David A. Black and Ruby Power and Light:
ADVANCING WITH RAILS April 14-17 New York City
INTRO TO RAILS June 9-12 Berlin
ADVANCING WITH RAILS June 16-19 Berlin
See http://www.rubypal.com for details and updates!
 
S

Saku Ytti

Having reject return the non-rejected entries is what I was referring
to. That's not how reject (with or without !) works, so if you want a
method that does that you'd want to find a different name for it.

Ok, so your intention with your example was to show how you think
reject! should work, return same array as the destination
would be after? Not an example run of how I wish it would work.
Then we can just agree to disagree :). I don't see any problem
foo! method returning different value than the value of
destination object after the method has finished.

Random core example:=> "moi"

Thanks,
 
D

David A. Black

Hi --

Ok, so your intention with your example was to show how you think
reject! should work, return same array as the destination
would be after? Not an example run of how I wish it would work.
Then we can just agree to disagree :). I don't see any problem
foo! method returning different value than the value of
destination object after the method has finished.

Random core example:
=> "moi"

There's no general principle at stake; I'm just saying that if you
want a method that behaves like select but performs an in-place
reject, it's better to invent a name than override Enumerable#reject!.


David

--
Rails training from David A. Black and Ruby Power and Light:
ADVANCING WITH RAILS April 14-17 New York City
INTRO TO RAILS June 9-12 Berlin
ADVANCING WITH RAILS June 16-19 Berlin
See http://www.rubypal.com for details and updates!
 
S

Saku Ytti

There's no general principle at stake; I'm just saying that if you
want a method that behaves like select but performs an in-place
reject, it's better to invent a name than override Enumerable#reject!.

I see what you mean, and I fully agree that changing existing
methods would cause lot of inconvenience. Kinda just wish this
functionality would be built-in (for performnce reasons), and
select!, reject!, delete_if! might be feasible candidates from
different points of view, if there wasn't history as a burden.
Anyhow than you for your insight.
 
A

ara.t.howard

I see what you mean, and I fully agree that changing existing
methods would cause lot of inconvenience. Kinda just wish this
functionality would be built-in (for performnce reasons), and
select!, reject!, delete_if! might be feasible candidates from
different points of view, if there wasn't history as a burden.
Anyhow than you for your insight.


think about that

[0, 1, 2, 3].reject!{|i| i.odd}

is going to do mutiple array replacements, so

[0,2,3]
[0,3]

shuffling an array like that all the way would KILL performance. you
need to build a new array and then replace all at once. of course
that is already there

a.replace a.select{|i| i.odd?}

which reads clearly and doesn't degrade to exponential array
shuffling...

food for though

a @ http://codeforpeople.com/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top