www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Removing an array's last item(s)?

reply AJG <AJG_member pathlink.com> writes:
Hi there,

I have a string buffer and I need to remove the last item out every once in a
while inside a loop. I see two options (both without templates):

# string buf;
# ...
#
# // [1] Resizing.
# buf.length = buf.length - 1;
#
# // [2] Slicing.
# buf = buf[0 .. length - 1];

My questions are:
[a] Which one do you guys recommend?
[b] Which one is more performant (at least in theory)?
[c] Is there a simpler/better/faster method that I haven't discovered?

Thanks a ton!
--AJG.

2B || !2B, that is the question.
================================
Jul 01 2005
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"AJG" <AJG_member pathlink.com> wrote in message 
news:da541b$2qdu$1 digitaldaemon.com...

Resizing a buffer to smaller than its original size is quite fast, as the 
system doesn't have to see if the buffer is overstepping its bounds, and if 
so, copy it.

Slicing may be slightly more expensive, simply because it has to construct a 
new array reference.  It's more obvious to say "arr.length=arr.length-1" 
than "arr=arr[0..length-2]", so I'd say use the "length" version. 
Jul 02 2005
next sibling parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message 
news:da6pq9$16f5$1 digitaldaemon.com...
 Slicing may be slightly more expensive, simply because it has to construct 
 a new array reference.  It's more obvious to say "arr.length=arr.length-1" 
 than "arr=arr[0..length-2]", so I'd say use the "length" version.

Oops, meant arr=arr[0..length-1].
Jul 02 2005
prev sibling next sibling parent reply AJG <AJG_member pathlink.com> writes:
Hi Jarrett,

Resizing a buffer to smaller than its original size is quite fast, as the 
system doesn't have to see if the buffer is overstepping its bounds, and if 
so, copy it.

That makes sense. Anybody think otherwise?
Slicing may be slightly more expensive, simply because it has to construct a 
new array reference.  It's more obvious to say "arr.length=arr.length-1" 
than "arr=arr[0..length-2]", so I'd say use the "length" version. 

I'll do that. How about this, though. Why can't I do: arr.length--; // or --arr.length; // not even: arr.length -= 1; // must do: arr.length = arr.length - 1; Seems kind of weird to me. Why is there this arbitrary restriction? Aren't they all semantically equivalent? If so, I think the syntax should support it. Thanks, --AJG. ======================= I sync, therefore I am.
Jul 03 2005
parent Chris Sauls <ibisbasenji gmail.com> writes:
AJG wrote:
 I'll do that. How about this, though. Why can't I do:
 
 arr.length--;
 // or
 --arr.length;
 // not even:
 arr.length -= 1;
 // must do:
 arr.length = arr.length - 1;
 
 Seems kind of weird to me. Why is there this arbitrary restriction? Aren't they
 all semantically equivalent? If so, I think the syntax should support it.

Well, while at first glance it sure isn't obvious, they actually aren't technically equivelant, because length is not a field/variable, its a property, and so it actually has method/function semantics. So, doing: # arr.length = arr.length - 1; Is sugar for: # arr.length(arr.length() - 1); At least that's my understanding. Personally I would think that ++/-- semantics could be provided, as long as the type of the property is appropriately integral, or else a class or struct defining op*Inc/op*Dec operators. I think the main reasoning why it isn't legal currently was something to do with expressions like: # arr[arr.length++] = 123; In what order is this evaluated? Personally I would have expected the index to be guaranteed to be evaluated fully before the rvalue, but from some old discussions I got the impression this actually isn't guaranteed. -- Chris Sauls
Jul 03 2005
prev sibling next sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Jarrett Billingsley wrote:
 "AJG" <AJG_member pathlink.com> wrote in message 
 news:da541b$2qdu$1 digitaldaemon.com...
 
 Resizing a buffer to smaller than its original size is quite fast, as the 
 system doesn't have to see if the buffer is overstepping its bounds, and if 
 so, copy it.

But it still needs to make sure arr.length-1 is non-negative. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Jul 04 2005
parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message 
news:dab8e8$rqh$1 digitaldaemon.com...
 But it still needs to make sure arr.length-1 is non-negative.

I'd imagine that'd go away in the release version. But you're right, it still has to make the check, although it's not as expensive as possibly copying the entire array when resizing to a larger size.
Jul 04 2005
prev sibling parent reply Nick <Nick_member pathlink.com> writes:
In article <da6pq9$16f5$1 digitaldaemon.com>, Jarrett Billingsley says...
"AJG" <AJG_member pathlink.com> wrote in message 
news:da541b$2qdu$1 digitaldaemon.com...

Resizing a buffer to smaller than its original size is quite fast, as the 
system doesn't have to see if the buffer is overstepping its bounds, and if 
so, copy it.

Slicing may be slightly more expensive, simply because it has to construct a 
new array reference.  It's more obvious to say "arr.length=arr.length-1" 
than "arr=arr[0..length-2]", so I'd say use the "length" version. 

Also, perhaps not relevant to your case, but important in general: they are not equivalent if you plan on growing the array again later. If you use .length to shrink and then grow the array, it is likely that the array will stay in the same place. But if you use a slice and then grow that, it will _always_ make a copy. Nick
Jul 08 2005
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Nick wrote:
<snip>
 Also, perhaps not relevant to your case, but important in general: they are not
 equivalent if you plan on growing the array again later. If you use .length to
 shrink and then grow the array, it is likely that the array will stay in the
 same place. But if you use a slice and then grow that, it will _always_ make a
 copy.

Wrong. An array reference consists of only two pieces of data: length and starting address. These pieces of information are identical whether you do arr.length = arr.length - 1; or arr = arr[0..$-1]; and so they are indistinguishable. OTOH if you make a slice that doesn't begin at the beginning of the array, then the slice doesn't have the starting address of any heap-allocated array, and so increasing the length will reallocate. Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++>++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Jul 08 2005
parent Nick <Nick_member pathlink.com> writes:
In article <dam6jc$apt$1 digitaldaemon.com>, Stewart Gordon says...
An array reference consists of only two pieces of data: length and 
starting address.  These pieces of information are identical whether you do

     arr.length = arr.length - 1;

or

     arr = arr[0..$-1];

and so they are indistinguishable.

OTOH if you make a slice that doesn't begin at the beginning of the 
array, then the slice doesn't have the starting address of any 
heap-allocated array, and so increasing the length will reallocate.

Stewart.

You are indeed correct. Thanks for clearing that up. Nick
Jul 08 2005