removing array item

J

J. J. Cale

I have the following. There must be something less cumbersome without push
pop. The function parameter obj is the event.srcElement and has the
attributes(properties?) picNum and alb pinned to it. The function is part of
a process to delete the selected obj, a photo in this case from the album
vis albumArr. TIA
Jimbo
function Album(albumName) {
this.name=albumName;
this.paths=new Array();
}
var albumArr(); // holds an array of Albums();
function removeArrSrc(obj) {
var dummy=new Array();
for(i=0;i<albumArr.length;i++) {
dummy=new Album(albumArr.name);
var el=albumArr.paths;
for(var j=0;j<el.length;j++) {
if(dummy.name==obj.alb) {
if(j==obj.picNum) continue;
}
var len=dummy.paths.length;
dummy.paths[len]=el[j];
}
}
albumArr=dummy;
}
 
M

Michael Winter

0123456789012345678901234567890123456789012345678901234567890123456789
I have the following. There must be something less cumbersome without
push pop. The function parameter obj is the event.srcElement

Is this for the Web, or just an IE-only environment?
and has the attributes(properties?) picNum and alb pinned to it. The
function is part of a process to delete the selected obj, a photo in
this case from the album vis albumArr. TIA
function Album(albumName) {
this.name=albumName;
this.paths=new Array();
}
var albumArr(); // holds an array of Albums();

I don't know what that's supposed to be, but I'm certain it'll cause an
error on most browsers. Perhaps you meant:

var albumArr = [];
function removeArrSrc(obj) {
var dummy=new Array();
for(i=0;i<albumArr.length;i++) {
dummy=new Album(albumArr.name);
var el=albumArr.paths;
for(var j=0;j<el.length;j++) {
if(dummy.name==obj.alb) {
if(j==obj.picNum) continue;
}
var len=dummy.paths.length;
dummy.paths[len]=el[j];
}
}
albumArr=dummy;
}


How about:

function removeArrSrc(o) {
var i = 0, n = albumArr.length;

// Find the element, 'o'
while(i < n && albumArr != o) {++i;}
// If 'o' exists in the array, 'i' will now point it
if(i < n) {
// Don't want to reach the last element
--n;
// Now shift the remaining elements down
while(i < n) {albumArr = albumArr[i + 1]; ++i;}
// Finally, truncate the array
albumArr.length = n;
}
}

which is removes the element in-place. You could also use:

function removeArrSrc(o) {
var i = 0, n = albumArr.length;

// Find the element, 'o'
while(i < n && albumArr != o) {++i;}
// If 'o' exists in the array, 'i' will now point it
if(i < n) {
albumArr = albumArr.slice(0, i).concat(albumArr.slice(i + 1));
}
}

which might be a little quicker (due to being performed by the browser),
but probably isn't (due to the resulting array allocations).

I haven't tested these, by the way.

Good luck,
Mike
 
J

J. J. Cale

Michael Winter said:
0123456789012345678901234567890123456789012345678901234567890123456789

Is this for the Web, or just an IE-only environment?

Ideally it would be generic although currently I'm writing an HTA.

paths array holds image paths
}
var albumArr(); // holds an array of Albums();

I don't know what that's supposed to be, but I'm certain it'll cause an
error on most browsers. Perhaps you meant:

var albumArr = [];
Sorry! It is declared var albumArr=new Array();
function removeArrSrc(obj) {
var dummy=new Array();
for(i=0;i<albumArr.length;i++) {
dummy=new Album(albumArr.name);
var el=albumArr.paths;
for(var j=0;j<el.length;j++) {
if(dummy.name==obj.alb) {
if(j==obj.picNum) continue;
}
var len=dummy.paths.length;
dummy.paths[len]=el[j];
}
}
albumArr=dummy;
}


How about:

function removeArrSrc(o) {
var i = 0, n = albumArr.length;

// Find the element, 'o'
while(i < n && albumArr != o) {++i;}

the array albumArr contains an array of Album objects. I need to delete
the path for one image.
the reference obj (here 'o') has the album name and the index in the
paths array pinned as attributes
I'm searching therefore for o.alb (the album name) and o.picNum the
offset into the paths array of the Album object.
while(i<n && albumArr.name != o.alb) {++i} should work to
find the album
// If 'o' exists in the array, 'i' will now point it
if(i < n) {
// Don't want to reach the last element
--n;
// Now shift the remaining elements down
while(i < n) {albumArr = albumArr[i + 1]; ++i;}
// Finally, truncate the array
albumArr.length = n;
}
}

This would delete the entire album. I need to delete the image from the
paths array of the album. The slice method with a regex is what I'm looking
for but I'm just getting into regex.
which is removes the element in-place. You could also use:

function removeArrSrc(o) {
var i = 0, n = albumArr.length;

// Find the element, 'o'
while(i < n && albumArr != o) {++i;}
// If 'o' exists in the array, 'i' will now point it
if(i < n) {
albumArr = albumArr.slice(0, i).concat(albumArr.slice(i + 1));
}
}

which might be a little quicker (due to being performed by the browser),
but probably isn't (due to the resulting array allocations).
I hope I've explained myself better this time. Thanks for the above

particularly because I haven't written the funtion to delete an album yet.
I'm sure this will do the job.
Jimbo
 
M

Michael Winter

[snip]
Is this for the Web, or just an IE-only environment?

Ideally it would be generic although currently I'm writing an HTA.

The reason I asked is that event.srcElement is IE-only. You'll also have
to check event.target, and possibly other properties, for the code to work
with other browsers. However, since you're writing a HTA, it isn't of much
concern at the moment.

[snip]
the array albumArr contains an array of Album objects. I need to
delete the path for one image.
Sorry.

the reference obj (here 'o') has the album name and the index in the
paths array pinned as attributes
I'm searching therefore for o.alb (the album name) and o.picNum the
offset into the paths array of the Album object.
while(i<n && albumArr.name != o.alb) {++i} should work
to find the album


Yes, it would.

[snip]
This would delete the entire album. I need to delete the image from the
paths array of the album. The slice method with a regex is what I'm
looking for but I'm just getting into regex.

I don't think that a regular expression would be terribly useful. Of
course, I'm not seeing the whole picture, so I could be wrong.

[snip]

function Album(albumName) {
this.name = albumName;
this.paths = [];
}
Album.prototype.removePath = function(i) {
for(var n = this.paths - 1; i < n; ++i) {
this.paths = this.paths[i + 1];
}
this.paths.length = n;
};

function removeArrSrc(o) {
for(var i = 0, n = albumArr.length; i < n; ++i) {
if(albumArr.name == o.alb) {
albumArr.removePath(o.picNum);
break;
}
}
}

I forsee a possible problem here. Say that you delete the first path
(picNum 0). In the paths array, all of the elements will shift making the
second path first, third path second, etc. If you then delete the second
path (picNum 1), you'll actually be deleting the third path from the
original list. Do you account for that?

Mike
 
T

Thomas 'PointedEars' Lahn

J. J. Cale said:
I have the following. There must be something less cumbersome without push
pop. The function parameter obj is the event.srcElement

which is IE only, use

function foo(e)
{
if (!e)
e = event;

if (e)
{
var t = e.target ? e.target : e.srcElement;
if (t)
{
// do something with t
}
}
}

<... on...="foo(event);" ...>...</...>

instead.
and has the attributes(properties?) picNum and alb pinned to it. The
function is part of a process to delete the selected obj, a photo in
this case from the album vis albumArr. TIA
Jimbo
function Album(albumName) {
this.name=albumName;
this.paths=new Array();
}
var albumArr(); // holds an array of Albums();

Invalid syntax. () is the call operator and can only be applied to
functions/methods.

var albumArr;

Watch the JavaScript Console or the status bar of the browser window!
function removeArrSrc(obj) {
var dummy=new Array();
for(i=0;i<albumArr.length;i++) {

Note that `i' is declared global here, causing mostly undesired
side effects. Use the `var' keyword (and optimize a bit):

for (var i = 0, len = albumArr.length; i < len; i++)
{
// ...
}

Since order does not seem to matter here, this can be
further optimized:

for (var i = albumArr.length; i--; 0)
{
// ...
}

This loops from the last element to the first.
dummy=new Album(albumArr.name);
[...]


To remove an array element, use the "delete" operator:

delete albumAr[42];

The array size will not be reduced, but further references
to albumAr[42] will return `undefined' instead of an Album
object reference which you can detect in your loop:

for (var i = albumAr.length; i--; 0)
{
if (albumAr)
{
delete albumAr;
}
}

More sophisticated but requires JavaScript 1.1 and compatibles:

for (var i = albumAr.length; i--; 0)
{
if (typeof albumAr != "undefined")
{
delete albumAr;
}
}

or

for (var i = albumAr.length; i--; 0)
{
if (albumAr && albumAr.constructor == Album)
{
delete albumAr;
}
}

Even more sophisticated but requires an ECMAScript 3 or later
implementation (e.g. JavaScript 1.5, JScript 5.6):

for (var i = albumAr.length; i--; 0)
{
if (albumAr instanceof Album)
{
delete albumAr;
}
}

You may want to add further conditions which must be matched
before the element will be deleted: your search parameters.


HTH

PointedEars

P.S.
Falsifying header information is not appropriate behavior (violating
several Usenet/Internet standards, the Netiquette and most certainly
the Acceptable Use Policy of service providers). It only *supports*
spammers' doing: <http://www.interhack.net/pubs/munging-harmful/>
 
L

Lasse Reichstein Nielsen

A few nitpicks:
function foo(e)
{
if (!e)
e = event;

these two lines are not necessary if you do:
<... on...="foo(event);" ...>...</...>

The event will be the argument to the function in all browsers (since
you pass it explicitly, and they all agree that "event" refers to the
event in an intrinsic event handler). It is needed (in IE) only when
you assign the function directly, as in:
something.onwhatever = foo;
Even more sophisticated but requires an ECMAScript 3 or later
implementation (e.g. JavaScript 1.5, JScript 5.6):

for (var i = albumAr.length; i--; 0)

This would start "i" out at albumAr.length, which is one past
the last element of the array. It should probably be
...(var i = albumAr.length - 1; ...

The "0" can also be omitted (all three expressions in a "for"
construct are optional).
 
T

Thomas 'PointedEars' Lahn

Lasse said:
Thomas 'PointedEars' Lahn said:
function foo(e)
{
if (!e)
e = event;

these two lines are not necessary if you do:
<... on...="foo(event);" ...>...</...>

[...] It is needed (in IE) only when
you assign the function directly, as in:
something.onwhatever = foo;

Correct, I confused both.
This would start "i" out at albumAr.length, which is one past
the last element of the array. It should probably be
...(var i = albumAr.length - 1; ...

No, it should not. The value of i is decreased the first time
the loop is executed.
The "0" can also be omitted (all three expressions in a "for"
construct are optional).

It cannot be omitted, the expressions are not optional in all
implementations.


PointedEars
 
R

Richard Cornford

Lasse said:
This would start "i" out at albumAr.length, which is one past
the last element of the array. It should probably be
...(var i = albumAr.length - 1; ...
<snip>

No, the first two expressions are fine. The - i-- - post decrements the
counter before its first use (assuming length was not zero, else there
would be no array access) leaving it the equivalent of length-1 when it
is first used.

Rihcard.
 
L

Lasse Reichstein Nielsen

Thomas 'PointedEars' Lahn said:
No, it should not. The value of i is decreased the first time
the loop is executed.

Ach, yes. The decrement is in the test, which is (apparently)
confuzing enough that I won't recommend it (for anything I have
to read :)
It cannot be omitted, the expressions are not optional in all
implementations.

Can you name one where it isn't?

All three expressions are optional in Javascript 1.0 (tested in
Netscape 2.02) and in ECMAScript v1.

/L
 
R

Randy Webb

Thomas said:
Lasse Reichstein Nielsen wrote:



It cannot be omitted, the expressions are not optional in all
implementations.

Can you quote one that does not allow them to be optional?
 
T

Thomas 'PointedEars' Lahn

Lasse said:
Can you name one where it isn't?

Micro$oft JScript, according to the MSDN Library, which IIRC matches
reality in IE 6 SP-1 on Win2k SP-4.
All three expressions are optional in Javascript 1.0 (tested in
Netscape 2.02) and in ECMAScript v1.

Yes, but non sequitur.


PointedEars
 
T

Thomas 'PointedEars' Lahn

J. J. Cale said:
news:eek:psdjinqrxx13kvk@atlantis...

Please do not write attribution novels and trim your quotes.
I don't know what that's supposed to be, but I'm certain it'll cause an
error on most browsers. Perhaps you meant:

var albumArr = [];
Sorry! It is declared var albumArr=new Array();

Both statements are equivalent, while the former (array literal) requires
AFAIK JavaScript 1.3 (supported from Netscape Navigator 4.0 on) and
compatibles, and later. If standards compliant, the implementation must
be standards compliant to ECMAScript 3.


Your Reply-To header still does not comply with Internet/Usenet standards.
(e-mail address removed). is not an e-mail address!


PointedEars
 
L

Lasse Reichstein Nielsen

Thomas 'PointedEars' Lahn said:
Micro$oft JScript, according to the MSDN Library, which IIRC matches
reality in IE 6 SP-1 on Win2k SP-4.

I don't have SP-1, but in IE 6 SP-2 (version
"6.0.2900.2180.xpsp_sp2_rtm.040803-2158") on WinXP, this script alerts
"10" as it should:
---
var x = 4;
var y = 0;
for(;;){y+=x--;if (!x) {break;}}
alert(y);
---
It seems to work as far back as IE 4 (I can't get IE 3 to run scripts)

The MSDN library is not a complete reference. There are features that
are not listed, and listed features that have unlisted exceptions.

I would be very surprised if there are any Javascript/ECMAScript/JScript-
implementations that doesn't allow you to omit all three expressions
of a "for", as that has been the expected behavior of the "for" construct
in all languages using a "C"-language-like "for" construct.

/L
 
T

Thomas 'PointedEars' Lahn

Lasse said:
I don't have SP-1, but in IE 6 SP-2 (version
"6.0.2900.2180.xpsp_sp2_rtm.040803-2158") on WinXP, this script alerts
"10" as it should:
---
var x = 4;
var y = 0;
for(;;){y+=x--;if (!x) {break;}}
alert(y);

Apparently, my mistake was to omit the trailing ";" in

for (var x = a.length; x--;)

Reincluding it, my example code also works in my IE (see above),
and yours works, of course.
The MSDN library is not a complete reference. There are features that
are not listed, and listed features that have unlisted exceptions.

Unfortunately, yes.
I would be very surprised if there are any Javascript/ECMAScript/JScript-
implementations that doesn't allow you to omit all three expressions
of a "for", as that has been the expected behavior of the "for" construct
in all languages using a "C"-language-like "for" construct.

Me too. According to the Client-side JavaScript 1.3 Reference,
they were already optional in JavaScript 1.0 (1995) and in the
first edition of ECMAScript (1997).


PointedEars
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top