[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

noob 'why doesn't this work' question

Vince Angeloni

4/14/2008 3:47:00 PM

Hi and greetings to all group members!

I'm a new Ruby user with a background in Applescript, Hypertalk
(Supercard), and a little Unix. I was intrigued by Matt Neuburg's
article about Applescript and Ruby, and that's what got me reading some
intro books on Ruby. I just bought Textmate and I am lovin' it!

Anyway, I am wondering why this seemingly simple script fails:

sizeList = [0,1,2,3,4,5,6]
countarray = [3,4,6]
countarray.each {|x| sizeList.delete_at(x)}

what I want to happen is that sizelist gets deleted at the positions
specified in countArray, but the result I am getting is:

0
1
2
4
6

and the expected result should be 0,1,2,5, right?
What gives?

TIA,
vince

Mac OS X 10.5.2, G5 Quad, Textmate editor, ruby 1.86
--
Posted via http://www.ruby-....

15 Answers

Jesús Gabriel y Galán

4/14/2008 3:58:00 PM

0

On Mon, Apr 14, 2008 at 5:47 PM, Vincent Angeloni <nospam7272@mac.com> wrote:
> Hi and greetings to all group members!
>
> I'm a new Ruby user with a background in Applescript, Hypertalk
> (Supercard), and a little Unix. I was intrigued by Matt Neuburg's
> article about Applescript and Ruby, and that's what got me reading some
> intro books on Ruby. I just bought Textmate and I am lovin' it!
>
> Anyway, I am wondering why this seemingly simple script fails:
>
> sizeList = [0,1,2,3,4,5,6]
> countarray = [3,4,6]
> countarray.each {|x| sizeList.delete_at(x)}
>
> what I want to happen is that sizelist gets deleted at the positions
> specified in countArray, but the result I am getting is:
>
> 0
> 1
> 2
> 4
> 6
>
> and the expected result should be 0,1,2,5, right?
> What gives?

Every time you delete an element, all the values to the right are
shifted one position. What you are doing essentially is:

irb(main):001:0> a = [0,1,2,3,4,5,6]
=> [0, 1, 2, 3, 4, 5, 6]
irb(main):002:0> a.delete_at(3)
=> 3
irb(main):003:0> a
=> [0, 1, 2, 4, 5, 6]
irb(main):004:0> a.delete_at(4)
=> 5
irb(main):005:0> a
=> [0, 1, 2, 4, 6]
irb(main):006:0> a.delete_at(6)
=> nil
irb(main):007:0> a
=> [0, 1, 2, 4, 6]

After the first delete_at, the elements 4,5 and 6 are shifted to fill the space
of the deleted element. So now, the element at index 4 is not the 4, it's the 5.
After those two deletions, the array no longer holds an element with index 6, so
the last deletion does nothing.

Hope this helps,

Jesus.

Joachim Glauche

4/14/2008 3:59:00 PM

0

Vincent Angeloni wrote:
> Hi and greetings to all group members!
>
> I'm a new Ruby user with a background in Applescript, Hypertalk
> (Supercard), and a little Unix. I was intrigued by Matt Neuburg's
> article about Applescript and Ruby, and that's what got me reading some
> intro books on Ruby. I just bought Textmate and I am lovin' it!
>
> Anyway, I am wondering why this seemingly simple script fails:
>
> sizeList = [0,1,2,3,4,5,6]
> countarray = [3,4,6]
> countarray.each {|x| sizeList.delete_at(x)}

> and the expected result should be 0,1,2,5, right?
> What gives?

Start counting at 0
--
Posted via http://www.ruby-....

Luis Lavena

4/14/2008 4:00:00 PM

0

On Apr 14, 12:47 pm, Vincent Angeloni <nospam7...@mac.com> wrote:
> Hi and greetings to all group members!
>
> I'm a new Ruby user with a background in Applescript, Hypertalk
> (Supercard), and a little Unix. I was intrigued by Matt Neuburg's
> article about Applescript and Ruby, and that's what got me reading some
> intro books on Ruby. I just bought Textmate and I am lovin' it!
>
> Anyway, I am wondering why this seemingly simple script fails:
>
> sizeList = [0,1,2,3,4,5,6]
> countarray = [3,4,6]
> countarray.each {|x| sizeList.delete_at(x)}
>
> what I want to happen is that sizelist gets deleted at the positions
> specified in countArray, but the result I am getting is:
>
> 0
> 1
> 2
> 4
> 6
>
> and the expected result should be 0,1,2,5, right?
> What gives?
>

Actually no, when you #delete_at one element from an array, the
indexes of it get altered too:

You can interpret what is doing #each on countarray:

irb(main):001:0> sizeList = [0,1,2,3,4,5,6]
=> [0, 1, 2, 3, 4, 5, 6]
irb(main):002:0> sizeList.delete_at(3)
=> 3
irb(main):003:0> sizeList.delete_at(4)
=> 5
irb(main):004:0> sizeList.delete_at(6)
=> nil

So, each time you iterate over countarray and remove the indicated
position, sizeList gets updated, and thus, the next items in the
countarray no longer reference your expected positions.

Errr, sound complicated my explanation, anyone with a better written
one? :-)

HTH,
--
Luis Lavena

Vince Angeloni

4/14/2008 4:16:00 PM

0

Luis Lavena wrote:
> On Apr 14, 12:47 pm, Vincent Angeloni <nospam7...@mac.com> wrote:
>> countarray = [3,4,6]
>>
>> and the expected result should be 0,1,2,5, right?
>> What gives?
>>
>
> Actually no, when you #delete_at one element from an array, the
> indexes of it get altered too:
>
> You can interpret what is doing #each on countarray:
>
> irb(main):001:0> sizeList = [0,1,2,3,4,5,6]
> => [0, 1, 2, 3, 4, 5, 6]
> irb(main):002:0> sizeList.delete_at(3)
> => 3
> irb(main):003:0> sizeList.delete_at(4)
> => 5
> irb(main):004:0> sizeList.delete_at(6)
> => nil
>
> So, each time you iterate over countarray and remove the indicated
> position, sizeList gets updated, and thus, the next items in the
> countarray no longer reference your expected positions.
>
> Errr, sound complicated my explanation, anyone with a better written
> one? :-)
>
> HTH,

Ah, yes. I knew it was something simple.
I'll just sort countarray so that the highest index value is first, and
perhaps that will take care of the problem!
Thank you.

vince
--
Posted via http://www.ruby-....

Karl von Laudermann

4/14/2008 5:25:00 PM

0

On Apr 14, 12:16 pm, Vincent Angeloni <nospam7...@mac.com> wrote:
>
> Ah, yes. I knew it was something simple.
> I'll just sort countarray so that the highest index value is first, and
> perhaps that will take care of the problem!
> Thank you.

Another approach would be: instead of deleting each item, put nil at
each specified array index. Then, after you're done iterating, delete
all the nils using Array#compact!, like so:

sizeList = [0,1,2,3,4,5,6]
countarray = [3,4,6]
countarray.each {|x| sizeList[x] = nil}
sizeList.compact!

Robert Klemme

4/14/2008 7:02:00 PM

0

On 14.04.2008 19:25, Karl von Laudermann wrote:
> On Apr 14, 12:16 pm, Vincent Angeloni <nospam7...@mac.com> wrote:
>> Ah, yes. I knew it was something simple.
>> I'll just sort countarray so that the highest index value is first, and
>> perhaps that will take care of the problem!
>> Thank you.
>
> Another approach would be: instead of deleting each item, put nil at
> each specified array index. Then, after you're done iterating, delete
> all the nils using Array#compact!, like so:
>
> sizeList = [0,1,2,3,4,5,6]

Btw, the conventional way in Ruby is to use "size_list" instead of
CamelCase for method and variable names.

> countarray = [3,4,6]
> countarray.each {|x| sizeList[x] = nil}
> sizeList.compact!

Yet another alternative is to delete based on /criteria/ and not /position/.

In this case that could be

# note, the array in the block is not the original
# array but contains entries to be deleted - it's
# only accidentally the same because of the way that
# size_list is built.
size_list.delete_if {|x| [3,4,6].include? x}

Or any other criterium.

Kind regards

robert

Marc Heiler

4/14/2008 11:06:00 PM

0

> I'm not entirely sure what you're trying to accomplish anyway

I guess he is starting to _learn_ which could explain what he
is wanting to accomplish so examples don't necessarily need to
make much sense and his head will slowly fill up with
101 ways to achieve what he wants to have ;-)
--
Posted via http://www.ruby-....

Vince Angeloni

4/15/2008 12:15:00 AM

0

Marc Heiler wrote:
>> I'm not entirely sure what you're trying to accomplish anyway
>
> I guess he is starting to _learn_ which could explain what he
> is wanting to accomplish so examples don't necessarily need to
> make much sense and his head will slowly fill up with
> 101 ways to achieve what he wants to have ;-)

Basically, I'm trying to get a list of files/folders along with
a separate list of the sizes of said files. The array deletions
I asked about would be the deletion of files enclosed in folders
from the original file list and using the position of the items
in the file list to delete the corresponding array position in
the separate size list of those files.

And thanks to everyone who responded. 101 ways to do this would
be great, but I'll settle for 4 or 5. ;-)

This has been very helpful.

vince

--
Posted via http://www.ruby-....

Peña, Botp

4/15/2008 2:08:00 AM

0

RnJvbTogbGlzdC1ib3VuY2VAZXhhbXBsZS5jb20gDQojIEFuZCB0aGFua3MgdG8gZXZlcnlvbmUg
d2hvIHJlc3BvbmRlZC4gMTAxIHdheXMgdG8gZG8gdGhpcyB3b3VsZA0KIyBiZSBncmVhdCwgYnV0
IEknbGwgc2V0dGxlIGZvciA0IG9yIDUuIDstKQ0KDQppIGhvcGUgdGhpcyBjYXRjaGVzIHVwIHRo
ZSA1dGggd2F5IDopDQoNCnJ1YnkxLjkgdGhvdWdoLA0KDQppcmIobWFpbik6MDA0OjA+IHNpemVM
aXN0Lmdyb3VwX2J5LndpdGhfaW5kZXh7fGUsaXwgY291bnRhcnJheS5pbmNsdWRlPyBpfQ0KPT4g
e2ZhbHNlPT5bMCwgMSwgMiwgNV0sIHRydWU9PlszLCA0LCA2XX0NCg0KZnIgaGVyZSB5b3UgY2Fu
IGdldCB3aGF0IGdldHMgZGVsZXRlZCwNCg0KaXJiKG1haW4pOjAxNjowPiBzaXplTGlzdC5ncm91
cF9ieS53aXRoX2luZGV4e3xlLGl8IGNvdW50YXJyYXkuaW5jbHVkZT8gaX1bdHJ1ZV0NCj0+IFsz
LCA0LCA2XQ0KDQphbmQgd2hhdCByZW1haW5zLA0KDQppcmIobWFpbik6MDE3OjA+IHNpemVMaXN0
Lmdyb3VwX2J5LndpdGhfaW5kZXh7fGUsaXwgY291bnRhcnJheS5pbmNsdWRlPyBpfVtmYWxzZV0N
Cj0+IFswLCAxLCAyLCA1XQ0KDQp0aGUgYmVhdXR5IGhlcmUgaXMgeW91IGNhbiBnbyBzbG93bHks
IGFuZCBwaWN0dXJlIG91dCBhbmQgY29tcGFyZSBpbiBhZHZhbmNlIHdoYXQgd2lsbCBiZSBkZWxl
dGVkIGFuZCB3aGF0IHdpbGwgcmVtYWluLi4uDQoNCmtpbmQgcmVnYXJkcyAtYm90cA0K

Paul

4/15/2008 7:02:00 AM

0

irb(main):001:0> a = [0,1,2,3,4,5,6]
=> [0, 1, 2, 3, 4, 5, 6]
irb(main):002:0> b = [3,4,6]
=> [3, 4, 6]
irb(main):003:0> c = a - b
=> [0, 1, 2, 5]
irb(main):004:0>