noob 'why doesn't this work' question

Discussion in 'Ruby' started by Vincent Angeloni, Apr 14, 2008.

  1. 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-forum.com/.
     
    Vincent Angeloni, Apr 14, 2008
    #1
    1. Advertising

  2. On Mon, Apr 14, 2008 at 5:47 PM, 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)}
    >
    > 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.
     
    Jesús Gabriel y Galán, Apr 14, 2008
    #2
    1. Advertising

  3. 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-forum.com/.
     
    Joachim Glauche, Apr 14, 2008
    #3
  4. Vincent Angeloni

    Luis Lavena Guest

    On Apr 14, 12:47 pm, 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)}
    >
    > 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
     
    Luis Lavena, Apr 14, 2008
    #4
  5. Luis Lavena wrote:
    > On Apr 14, 12:47 pm, Vincent Angeloni <> 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-forum.com/.
     
    Vincent Angeloni, Apr 14, 2008
    #5
  6. On Apr 14, 12:16 pm, Vincent Angeloni <> 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!
     
    Karl von Laudermann, Apr 14, 2008
    #6
  7. On 14.04.2008 19:25, Karl von Laudermann wrote:
    > On Apr 14, 12:16 pm, Vincent Angeloni <> 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
     
    Robert Klemme, Apr 14, 2008
    #7
  8. Vincent Angeloni

    Marc Heiler Guest

    > 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-forum.com/.
     
    Marc Heiler, Apr 15, 2008
    #8
  9. 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-forum.com/.
     
    Vincent Angeloni, Apr 15, 2008
    #9
  10. RnJvbTogbGlzdC1ib3VuY2VAZXhhbXBsZS5jb20gDQojIEFuZCB0aGFua3MgdG8gZXZlcnlvbmUg
    d2hvIHJlc3BvbmRlZC4gMTAxIHdheXMgdG8gZG8gdGhpcyB3b3VsZA0KIyBiZSBncmVhdCwgYnV0
    IEknbGwgc2V0dGxlIGZvciA0IG9yIDUuIDstKQ0KDQppIGhvcGUgdGhpcyBjYXRjaGVzIHVwIHRo
    ZSA1dGggd2F5IDopDQoNCnJ1YnkxLjkgdGhvdWdoLA0KDQppcmIobWFpbik6MDA0OjA+IHNpemVM
    aXN0Lmdyb3VwX2J5LndpdGhfaW5kZXh7fGUsaXwgY291bnRhcnJheS5pbmNsdWRlPyBpfQ0KPT4g
    e2ZhbHNlPT5bMCwgMSwgMiwgNV0sIHRydWU9PlszLCA0LCA2XX0NCg0KZnIgaGVyZSB5b3UgY2Fu
    IGdldCB3aGF0IGdldHMgZGVsZXRlZCwNCg0KaXJiKG1haW4pOjAxNjowPiBzaXplTGlzdC5ncm91
    cF9ieS53aXRoX2luZGV4e3xlLGl8IGNvdW50YXJyYXkuaW5jbHVkZT8gaX1bdHJ1ZV0NCj0+IFsz
    LCA0LCA2XQ0KDQphbmQgd2hhdCByZW1haW5zLA0KDQppcmIobWFpbik6MDE3OjA+IHNpemVMaXN0
    Lmdyb3VwX2J5LndpdGhfaW5kZXh7fGUsaXwgY291bnRhcnJheS5pbmNsdWRlPyBpfVtmYWxzZV0N
    Cj0+IFswLCAxLCAyLCA1XQ0KDQp0aGUgYmVhdXR5IGhlcmUgaXMgeW91IGNhbiBnbyBzbG93bHks
    IGFuZCBwaWN0dXJlIG91dCBhbmQgY29tcGFyZSBpbiBhZHZhbmNlIHdoYXQgd2lsbCBiZSBkZWxl
    dGVkIGFuZCB3aGF0IHdpbGwgcmVtYWluLi4uDQoNCmtpbmQgcmVnYXJkcyAtYm90cA0K
     
    Peña, Botp, Apr 15, 2008
    #10
  11. Vincent Angeloni

    Paul Guest

    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>
     
    Paul, Apr 15, 2008
    #11
  12. Vincent Angeloni

    Peña, Botp Guest

    From: Paul [mailto:p]=20
    # irb(main):001:0> a =3D [0,1,2,3,4,5,6]
    # =3D> [0, 1, 2, 3, 4, 5, 6]
    # irb(main):002:0> b =3D [3,4,6]
    # =3D> [3, 4, 6]
    # irb(main):003:0> c =3D a - b
    # =3D> [0, 1, 2, 5]

    Hi Paul, the op meant that the array b contains indexes for a (and not =
    contents as in your example)

    kind regards -botp
     
    Peña, Botp, Apr 15, 2008
    #12
  13. RnJvbTogUGXDsWEsIEJvdHAgW21haWx0bzpib3RwQGRlbG1vbnRlLXBoaWwuY29tXSANCiMgaXJi
    KG1haW4pOjAwNDowPiBzaXplTGlzdC5ncm91cF9ieS53aXRoX2luZGV4e3xlLGl8IA0KIyBjb3Vu
    dGFycmF5LmluY2x1ZGU/IGl9DQojID0+IHtmYWxzZT0+WzAsIDEsIDIsIDVdLCB0cnVlPT5bMywg
    NCwgNl19DQoNCjZ0aCB3YXkgOikNCg0KOjA+IHNpemVMaXN0LnZhbHVlc19hdCgqKDAuLnNpemVM
    aXN0LnNpemUtMSkudG9fYS1jb3VudGFycmF5KQ0KPT4gWzAsIDEsIDIsIDVdDQoNCnRoaXMgb25l
    IHBsYXlzIHcgdGhlIGluZGljZXMsIHRoZW4gdXNlcyB2YWx1ZXNfYXQgdG8gZ2V0IGJhY2sgdG8g
    dGhlIGNvbnRlbnRzLg0KDQpraW5kIHJlZ2FyZHMgLWJvdHANCg==
     
    Peña, Botp, Apr 15, 2008
    #13
  14. On Tue, Apr 15, 2008 at 2:14 AM, Vincent Angeloni <> wrote:

    > 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.


    Another solution could be, instead of having 2 arrays, to have
    a single array where each position contains all the info for
    a file, maybe like an array or hash, and then delete based on
    the size info. Example:

    file_info = [["a.txt", 123], ["b.txt", 10000]]
    file_info.delete_if {|x| x[1] > 1000}

    will delete all entries whose size is bigger than 1000.

    As a hash:

    file_info = [{:name => "a.txt", :size => 123}, {:name => "b.txt",
    :size => 10000}]
    file_info.delete_if {|x| x[:size] > 1000}

    or you could have a custom object if you need more complex modelling
    of the file info.

    Hope this helps,

    Jesus.
     
    Jesús Gabriel y Galán, Apr 15, 2008
    #14
  15. On Apr 14, 5:47 pm, 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)}
    >
    > 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


    What about this:

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

    Result: 0,1,2,5
     
    Robin Pedersen, Apr 15, 2008
    #15
  16. [Note: parts of this message were removed to make it a legal post.]

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

    Let's look at what's going on inside your .each block.
    The first iteration it will delete the sizeList[3]. ===> [0,1,2,4,5,6]
    The second iteration it will delete sizeList[4] ===> [0,1,2,4,6]
    The final iteration it will delete sizeList[6] ==> [0,1,2,4,6] #there
    is no sizeList[6] - deleteAt returns nil.

    Your indexs are changing each time you call delete_at.

    -Stephen





    On Tue, Apr 15, 2008 at 9:15 AM, Robin Pedersen <>
    wrote:

    > On Apr 14, 5:47 pm, 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)}
    > >
    > > 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

    >
    > What about this:
    >
    > sizeList = [0,1,2,3,4,5,6]
    > countarray = [3,4,6]
    > countarray.sort.reverse.each {|x| sizeList.delete_at(x)}
    >
    > Result: 0,1,2,5
    >
    >
     
    Stephen Schor, Apr 15, 2008
    #16
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. David Prowak

    Why oh why doesn't my data view work?

    David Prowak, Jan 30, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    745
    Alvin Bruney [MVP]
    Jan 30, 2004
  2. Bouke Woudstra

    (noob alert) why doesn't this work?

    Bouke Woudstra, Mar 22, 2005, in forum: Python
    Replies:
    1
    Views:
    262
    Diez B. Roggisch
    Mar 22, 2005
  3. Bouke Woudstra

    Re: (noob alert) why doesn't this work?

    Bouke Woudstra, Mar 22, 2005, in forum: Python
    Replies:
    2
    Views:
    275
    Bengt Richter
    Mar 23, 2005
  4. Mr. SweatyFinger

    why why why why why

    Mr. SweatyFinger, Nov 28, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    921
    Mark Rae
    Dec 21, 2006
  5. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,073
    Smokey Grindel
    Dec 2, 2006
Loading...

Share This Page