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

On Apr 11, 2008, at 2:40 PM, Saku Y. wrote:

I was more thinking something along the lines

foo = {}
(‘a’…‘z’).each { |l| foo[l] = somearray.select {dosomething} }

So I’d be populating foo hash, with values from somearray according
to some magic. If I’d know I only need to use each value of somearray
once, it would make sense to ‘pop’ the values out from the somearray
in-place.

[ ‘a’, ‘a’, ‘a’ ].select{|x| x == ‘a’}

and you’ve clobbered… not to mention it loses ordering. the only
thing which has semantics inline with that of select is

a.replace a.select(&condition)

which preserves ordering and allows for duplicates.

cheers.

a @ http://codeforpeople.com/

On Apr 11, 2008, at 2:07 PM, Saku Y. wrote:

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/

2008/4/11, Saku Y. [email protected]:

different points of view, if there wasn’t history as a burden.
Anyhow than you for your insight.

Here are a few nearly built in ways:

irb(main):001:0> a = (1…10).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
irb(main):002:0> a,b = a.partition {|x| x % 2 == 0}
=> [[2, 4, 6, 8, 10], [1, 3, 5, 7, 9]]
irb(main):003:0> a
=> [2, 4, 6, 8, 10]
irb(main):004:0> b

irb(main):005:0> a = (1…10).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
irb(main):006:0> b = []
=> []
irb(main):007:0> a.delete_if {|x| x % 2 != 0 and b << x}
=> [2, 4, 6, 8, 10]
irb(main):008:0> a
=> [2, 4, 6, 8, 10]
irb(main):009:0> b
=> [1, 3, 5, 7, 9]

irb(main):010:0> a = (1…10).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
irb(main):011:0> b = []
=> []
irb(main):012:0> a.reject! {|x| x % 2 != 0 and b << x}
=> [2, 4, 6, 8, 10]
irb(main):013:0> a
=> [2, 4, 6, 8, 10]
irb(main):014:0> b
=> [1, 3, 5, 7, 9]

Cheers

robert

On (2008-04-12 08:27 +0900), ara.t.howard wrote:

which preserves ordering and allows for duplicates.
Yes but if condition needs variable from outer loop (that is, in
my example, you’d use the ‘l’ from Range object in the ‘dosomething’
block, so you’re walking through the array multiple times.
If you positively know, you want to pick each element exactly once
to a new array/hash. Then having select that reduces the array size
by not forcing you to look at elements you know you’re not going
to pick up (as they were already picked up by earlier condition,
to a earlier hash/array, and you know, no future condition can any more
be true for them). If array would be extremely large, the loop
would get the faster the closer to end it is, as array would keep
shrinking.

Thanks,