Remove specified value from array

S

Sam Collett

How do I remove an item with a specified value from an array?

i.e. array values 1,2,2,5,7,12,15,21

remove 2 from array would return
1,5,7,12,15,21

(12 and 21 are NOT removed, duplicates are also removed)

So far I have (val is value, ar is array, returns new array):

function removeFromArray(val, ar){
s = String(ar)
// remove if not first item (global search)
reRemove = new RegExp(","+val,"g")
s = s.replace(reRemove,"")
// remove if at start of array
reRemove = new RegExp("^"+val+",")
s = s.replace(reRemove,"")
// remove if only item
reRemove = new RegExp("^"+val+"$")
s = s.replace(reRemove,"")
return new Array(s)
}

However this seems to return 1,5,7,12,151 (the 151 is a result of the
',2' being removed from the '15,21' part of the array)

How would I modify this to get it to work properly (maybe as one
regular expression - broken down and explained though)?

Also I want it to work with strings as well (possibly containing
commas)

i.e.

array = "Bloggs, Jo", "Doe, John", "Doe, Jane"
remove "Doe, Jane" from array to return "Bloggs, Jo","Doe, John"
 
G

Grant Wagner

Sam said:
How do I remove an item with a specified value from an array?

i.e. array values 1,2,2,5,7,12,15,21

remove 2 from array would return
1,5,7,12,15,21

(12 and 21 are NOT removed, duplicates are also removed)

So far I have (val is value, ar is array, returns new array):

function removeFromArray(val, ar){
s = String(ar)
// remove if not first item (global search)
reRemove = new RegExp(","+val,"g")
s = s.replace(reRemove,"")
// remove if at start of array
reRemove = new RegExp("^"+val+",")
s = s.replace(reRemove,"")
// remove if only item
reRemove = new RegExp("^"+val+"$")
s = s.replace(reRemove,"")
return new Array(s)
}

However this seems to return 1,5,7,12,151 (the 151 is a result of the
',2' being removed from the '15,21' part of the array)

How would I modify this to get it to work properly (maybe as one
regular expression - broken down and explained though)?

Also I want it to work with strings as well (possibly containing
commas)

i.e.

array = "Bloggs, Jo", "Doe, John", "Doe, Jane"
remove "Doe, Jane" from array to return "Bloggs, Jo","Doe, John"

First you say you want to remove values from an array, then you don't use
a JavaScript Array object at all. That doesn't make much sense to me. If
you want to remove items from an array, then remove items from an array:

<script type="text/javascript">
var theArray = [ 1,2,2,5,7,12,15,21 ];

var theNewArray = removeItems(theArray, 2);
alert(theNewArray.join(", "));

function removeItems(array, item) {
var i = 0;
while (i < array.length) {
if (array == item) {
array.splice(i, 1);
} else {
i++;
}
}
return array;
}
</script>

But, you say to me, "I don't have an array like that". No problem, say
you have the items in a comma-delimited string as original shown:

var theValues = "1,2,2,5,7,12,15,21";
var theArray = theValues.split(/,/);

Doing it for names would work just as well:

var theNewArray = (theNamesArray, "Doe, John");

The only problem would be turning your comma-delimited list of names into
an array. "'Doe, John', 'Smith, Joe'" couldn't be turned into an array by
..split(/,/). There are a number of solutions to this, however the easiest
would be to use another delimiter (one that is unlikely to appear as part
of a person's name in the original string):

var theNames = "'Doe, John'@#!'Smith, Joe'@#!'Jones, Mary'";
var theNamesArray = theNames.split(/@#!/);

Better still, store the first and last names as two properties of an
object, then store that object in the array.

--
| Grant Wagner <[email protected]>

* Client-side Javascript and Netscape 4 DOM Reference available at:
*
http://devedge.netscape.com/library/manuals/2000/javascript/1.3/reference/frames.html

* Internet Explorer DOM Reference available at:
*
http://msdn.microsoft.com/workshop/author/dhtml/reference/dhtml_reference_entry.asp

* Netscape 6/7 DOM Reference available at:
* http://www.mozilla.org/docs/dom/domref/
* Tips for upgrading JavaScript for Netscape 6/7 and Mozilla
* http://www.mozilla.org/docs/web-developer/upgrade_2.html
 
D

Douglas Crockford

How do I remove an item with a specified value from an array?
i.e. array values 1,2,2,5,7,12,15,21

remove 2 from array would return
1,5,7,12,15,21

(12 and 21 are NOT removed, duplicates are also removed)

So far I have (val is value, ar is array, returns new array):

function removeFromArray(val, ar){
s = String(ar)
// remove if not first item (global search)
reRemove = new RegExp(","+val,"g")
s = s.replace(reRemove,"")
// remove if at start of array
reRemove = new RegExp("^"+val+",")
s = s.replace(reRemove,"")
// remove if only item
reRemove = new RegExp("^"+val+"$")
s = s.replace(reRemove,"")
return new Array(s)
}

However this seems to return 1,5,7,12,151 (the 151 is a result of the
',2' being removed from the '15,21' part of the array)

How would I modify this to get it to work properly (maybe as one
regular expression - broken down and explained though)?

Also I want it to work with strings as well (possibly containing
commas)

i.e.

array = "Bloggs, Jo", "Doe, John", "Doe, Jane"
remove "Doe, Jane" from array to return "Bloggs, Jo","Doe, John"

Mother of pearl! Arrays are useful data structures. You ought not to be
transforming out of array space into string space and doing RegExp operations.
That is wildly inefficient and error prone. Stay in array space.

If you know the subscript of the element to delete, you can use the splice()
method to extract it. So,

var my_array = [1,2,2,5,7,12,15,21];
my_array.splice(1, 2);

my_array now contains [1,5,7,12,15,21];

Similarly,

my_array = ["Bloggs, Jo", "Doe, John", "Doe, Jane"];
my_array.splice(2, 1);

my_array now contains ["Bloggs, Jo", "Doe, John"].

You can find the subscripts of the elements with a for loop.

http://www.crockford.com/javascript/remedial.html
 
D

Dr John Stockton

JRS: In article <[email protected]>, seen
How do I remove an item with a specified value from an array?

The following is for removing undefined values from an array; note that
u is undefined. Define u as being the value to be removed, and ISTM
that it should work. Consider the ===, which can be == if u is defined
(? depending on whether you think '2' == 2 ?).

function scanReduce(A) { // After Dom Leonard, c.l.j, 2003-07-15
var u, i=-1, j=-1, k=A.length
while (++j < k) if (!(A[j]===u)) A[++i]=A[j]
A.length = ++i
return A }
 
D

Dr John Stockton

JRS: In article <[email protected]>, seen in
If you know the subscript of the element to delete, you can use the splice()
method to extract it. So,

var my_array = [1,2,2,5,7,12,15,21];
my_array.splice(1, 2);

There are two small problems with .splice() - it's not in older
javascript, and it looks horribly like a typo for .slice() .

It's a pity that the example uses 2 in the array; it would be better
with all elements larger by say 50.
 
G

Grant Wagner

Actually, given your initial variables:

var theArray = [ 1,2,2,5,7,12,15,21 ];
var toRemove = [ 1,7 ]
var theNewArray = removeItems(theArray, toRemove);

The resulting array should be 2,2,5,12,15,21 not 1,5,12,15,21

Anyway, use nested loops. Just repeat the original code for each value passed in:

<script type="text/javascript">
var theArray = [ 1,2,2,5,7,12,15,21 ];
var toRemove = [ 1,7 ];
var theNewArray = removeItems(theArray, toRemove);
alert(theNewArray);

function removeItems(originalArray, itemsToRemove) {
var j;
for (var i = 0; i < itemsToRemove.length; i++) {
j = 0;
while (j < originalArray.length) {
if (originalArray[j] == itemsToRemove) {
originalArray.splice(j, 1);
} else {
j++;
}
}
}
return originalArray;
}
</script>

Actually, I'd make removeItems() a method of the Array object:

Array.prototype.removeItems = function(itemsToRemove) {
var j;
for (var i = 0; i < itemsToRemove.length; i++) {
j = 0;
while (j < this.length) {
if (this[j] == itemsToRemove) {
this.splice(j, 1);
} else {
j++;
}
}
}
}
theArray.removeItems(toRemove);
alert(theArray);

Note, this only works for comparable data types (Number, String). If the contents of the array are a more
complex object (such as another Array), then you'll need a method that allows you to evaluate their equality
(== won't do it).

I hope I get a good mark from your instructor for this.


Sam said:
I wasn't sure how to do it using the array object so thought that
using regular expressions would be the solution (i.e. converting the
array to a string and then back into an array after performing the
removal)

Now that you go through it though it seems as though I didn't think of
the obvious (looping though the array and splicing it when the item
was found).

The next step is to try to remove an array of items from the original
array.

e.g.
var theArray = [ 1,2,2,5,7,12,15,21 ];
var toRemove = [ 1,7 ]
var theNewArray = removeItems(theArray, toRemove);

returns 1,5,12,15,21

Would it be possible to do a check to see if the second parameter
(toRemove) is an array or a string, performing a loop on the toRemove
if it is an array?

Maybe it would be simpler to do a nested loop in the function
(converting toRemove to an array, even if the supplied value is a
number or a string)?

Thanks for the help

Grant Wagner said:
Sam said:
How do I remove an item with a specified value from an array?

i.e. array values 1,2,2,5,7,12,15,21

remove 2 from array would return
1,5,7,12,15,21

(12 and 21 are NOT removed, duplicates are also removed)

So far I have (val is value, ar is array, returns new array):

function removeFromArray(val, ar){
s = String(ar)
// remove if not first item (global search)
reRemove = new RegExp(","+val,"g")
s = s.replace(reRemove,"")
// remove if at start of array
reRemove = new RegExp("^"+val+",")
s = s.replace(reRemove,"")
// remove if only item
reRemove = new RegExp("^"+val+"$")
s = s.replace(reRemove,"")
return new Array(s)
}

However this seems to return 1,5,7,12,151 (the 151 is a result of the
',2' being removed from the '15,21' part of the array)

How would I modify this to get it to work properly (maybe as one
regular expression - broken down and explained though)?

Also I want it to work with strings as well (possibly containing
commas)

i.e.

array = "Bloggs, Jo", "Doe, John", "Doe, Jane"
remove "Doe, Jane" from array to return "Bloggs, Jo","Doe, John"

First you say you want to remove values from an array, then you don't use
a JavaScript Array object at all. That doesn't make much sense to me. If
you want to remove items from an array, then remove items from an array:

<script type="text/javascript">
var theArray = [ 1,2,2,5,7,12,15,21 ];

var theNewArray = removeItems(theArray, 2);
alert(theNewArray.join(", "));

function removeItems(array, item) {
var i = 0;
while (i < array.length) {
if (array == item) {
array.splice(i, 1);
} else {
i++;
}
}
return array;
}
</script>

But, you say to me, "I don't have an array like that". No problem, say
you have the items in a comma-delimited string as original shown:

var theValues = "1,2,2,5,7,12,15,21";
var theArray = theValues.split(/,/);

Doing it for names would work just as well:

var theNewArray = (theNamesArray, "Doe, John");

The only problem would be turning your comma-delimited list of names into
an array. "'Doe, John', 'Smith, Joe'" couldn't be turned into an array by
.split(/,/). There are a number of solutions to this, however the easiest
would be to use another delimiter (one that is unlikely to appear as part
of a person's name in the original string):

var theNames = "'Doe, John'@#!'Smith, Joe'@#!'Jones, Mary'";
var theNamesArray = theNames.split(/@#!/);

Better still, store the first and last names as two properties of an
object, then store that object in the array.


--
| Grant Wagner <[email protected]>

* Client-side Javascript and Netscape 4 DOM Reference available at:
* http://devedge.netscape.com/library/manuals/2000/javascript/1.3/reference/frames.html
* Internet Explorer DOM Reference available at:
* http://msdn.microsoft.com/workshop/author/dhtml/reference/dhtml_reference_entry.asp
* Netscape 6/7 DOM Reference available at:
* http://www.mozilla.org/docs/dom/domref/
* Tips for upgrading JavaScript for Netscape 6/7 and Mozilla
* http://www.mozilla.org/docs/web-developer/upgrade_2.html
 
G

Greg

I wasn't sure how to do it using the array object so thought that
using regular expressions would be the solution (i.e. converting the
array to a string and then back into an array after performing the
removal)

Now that you go through it though it seems as though I didn't think of
the obvious (looping though the array and splicing it when the item
was found).

The next step is to try to remove an array of items from the original
array.

e.g.
var theArray = [ 1,2,2,5,7,12,15,21 ];
var toRemove = [ 1,7 ]
var theNewArray = removeItems(theArray, toRemove);

returns 1,5,12,15,21

Would it be possible to do a check to see if the second parameter
(toRemove) is an array or a string, performing a loop on the toRemove
if it is an array?

Maybe it would be simpler to do a nested loop in the function
(converting toRemove to an array, even if the supplied value is a
number or a string)?

Thanks for the help

Grant Wagner said:
Sam said:
How do I remove an item with a specified value from an array?

i.e. array values 1,2,2,5,7,12,15,21

remove 2 from array would return
1,5,7,12,15,21

(12 and 21 are NOT removed, duplicates are also removed)

So far I have (val is value, ar is array, returns new array):

function removeFromArray(val, ar){
s = String(ar)
// remove if not first item (global search)
reRemove = new RegExp(","+val,"g")
s = s.replace(reRemove,"")
// remove if at start of array
reRemove = new RegExp("^"+val+",")
s = s.replace(reRemove,"")
// remove if only item
reRemove = new RegExp("^"+val+"$")
s = s.replace(reRemove,"")
return new Array(s)
}

However this seems to return 1,5,7,12,151 (the 151 is a result of the
',2' being removed from the '15,21' part of the array)

How would I modify this to get it to work properly (maybe as one
regular expression - broken down and explained though)?

Also I want it to work with strings as well (possibly containing
commas)

i.e.

array = "Bloggs, Jo", "Doe, John", "Doe, Jane"
remove "Doe, Jane" from array to return "Bloggs, Jo","Doe, John"

First you say you want to remove values from an array, then you don't use
a JavaScript Array object at all. That doesn't make much sense to me. If
you want to remove items from an array, then remove items from an array:

<script type="text/javascript">
var theArray = [ 1,2,2,5,7,12,15,21 ];

var theNewArray = removeItems(theArray, 2);
alert(theNewArray.join(", "));

function removeItems(array, item) {
var i = 0;
while (i < array.length) {
if (array == item) {
array.splice(i, 1);
} else {
i++;
}
}
return array;
}
</script>

But, you say to me, "I don't have an array like that". No problem, say
you have the items in a comma-delimited string as original shown:

var theValues = "1,2,2,5,7,12,15,21";
var theArray = theValues.split(/,/);

Doing it for names would work just as well:

var theNewArray = (theNamesArray, "Doe, John");

The only problem would be turning your comma-delimited list of names into
an array. "'Doe, John', 'Smith, Joe'" couldn't be turned into an array by
.split(/,/). There are a number of solutions to this, however the easiest
would be to use another delimiter (one that is unlikely to appear as part
of a person's name in the original string):

var theNames = "'Doe, John'@#!'Smith, Joe'@#!'Jones, Mary'";
var theNamesArray = theNames.split(/@#!/);

Better still, store the first and last names as two properties of an
object, then store that object in the array.

--
| Grant Wagner <[email protected]>

* Client-side Javascript and Netscape 4 DOM Reference available at:
*
http://devedge.netscape.com/library/manuals/2000/javascript/1.3/reference/frames.html

* Internet Explorer DOM Reference available at:
*
http://msdn.microsoft.com/workshop/author/dhtml/reference/dhtml_reference_entry.asp

* Netscape 6/7 DOM Reference available at:
* http://www.mozilla.org/docs/dom/domref/
* Tips for upgrading JavaScript for Netscape 6/7 and Mozilla
* http://www.mozilla.org/docs/web-developer/upgrade_2.html


I'm no expert, but I think that your regex idea would work with a
little modification. Here's an example that seems to work:

<script type='text/javascript'>
function removeVal(arr, valToRemove){
// Normalize to a string like !val!!val!!val!
var s = '!' + arr.join('!!') + '!';
// Remove targeted values with delimiters
s = s.replace(new RegExp('!' + valToRemove + '!', 'g'), '');
// Remove delimiter added to end in step 1
s = s.replace(/^!/, '');
// Remove delimiter added to start in step 1
s = s.replace(/!$/, '');
// Convert to array
return s.split('!!');
}

function test(){
var arr = [2,1,2,2,5,7,12,15,21,2]; // Check case with end vals
var s = arr.toString();
arr = removeVal(arr, 2)
alert(s + '\n' + arr.toString());
}
</script>

<button onclick='test()' />test()</button>
 
S

Sam Collett

Thanks for that. Don't know how I got the wrong resulting array
(should have double checked before I posted).

This is actually for an ASP page I was doing, but I use javascript
server-side (instead of VBScript) as it is easily migrated over to
client-side.

Grant Wagner said:
Actually, given your initial variables:

var theArray = [ 1,2,2,5,7,12,15,21 ];
var toRemove = [ 1,7 ]
var theNewArray = removeItems(theArray, toRemove);

The resulting array should be 2,2,5,12,15,21 not 1,5,12,15,21

Anyway, use nested loops. Just repeat the original code for each value passed in:

<script type="text/javascript">
var theArray = [ 1,2,2,5,7,12,15,21 ];
var toRemove = [ 1,7 ];
var theNewArray = removeItems(theArray, toRemove);
alert(theNewArray);

function removeItems(originalArray, itemsToRemove) {
var j;
for (var i = 0; i < itemsToRemove.length; i++) {
j = 0;
while (j < originalArray.length) {
if (originalArray[j] == itemsToRemove) {
originalArray.splice(j, 1);
} else {
j++;
}
}
}
return originalArray;
}
</script>

Actually, I'd make removeItems() a method of the Array object:

Array.prototype.removeItems = function(itemsToRemove) {
var j;
for (var i = 0; i < itemsToRemove.length; i++) {
j = 0;
while (j < this.length) {
if (this[j] == itemsToRemove) {
this.splice(j, 1);
} else {
j++;
}
}
}
}
theArray.removeItems(toRemove);
alert(theArray);

Note, this only works for comparable data types (Number, String). If the contents of the array are a more
complex object (such as another Array), then you'll need a method that allows you to evaluate their equality
(== won't do it).

I hope I get a good mark from your instructor for this.


Sam said:
I wasn't sure how to do it using the array object so thought that
using regular expressions would be the solution (i.e. converting the
array to a string and then back into an array after performing the
removal)

Now that you go through it though it seems as though I didn't think of
the obvious (looping though the array and splicing it when the item
was found).

The next step is to try to remove an array of items from the original
array.

e.g.
var theArray = [ 1,2,2,5,7,12,15,21 ];
var toRemove = [ 1,7 ]
var theNewArray = removeItems(theArray, toRemove);

returns 1,5,12,15,21

Would it be possible to do a check to see if the second parameter
(toRemove) is an array or a string, performing a loop on the toRemove
if it is an array?

Maybe it would be simpler to do a nested loop in the function
(converting toRemove to an array, even if the supplied value is a
number or a string)?

Thanks for the help

Grant Wagner said:
Sam Collett wrote:

How do I remove an item with a specified value from an array?

i.e. array values 1,2,2,5,7,12,15,21

remove 2 from array would return
1,5,7,12,15,21

(12 and 21 are NOT removed, duplicates are also removed)

So far I have (val is value, ar is array, returns new array):

function removeFromArray(val, ar){
s = String(ar)
// remove if not first item (global search)
reRemove = new RegExp(","+val,"g")
s = s.replace(reRemove,"")
// remove if at start of array
reRemove = new RegExp("^"+val+",")
s = s.replace(reRemove,"")
// remove if only item
reRemove = new RegExp("^"+val+"$")
s = s.replace(reRemove,"")
return new Array(s)
}

However this seems to return 1,5,7,12,151 (the 151 is a result of the
',2' being removed from the '15,21' part of the array)

How would I modify this to get it to work properly (maybe as one
regular expression - broken down and explained though)?

Also I want it to work with strings as well (possibly containing
commas)

i.e.

array = "Bloggs, Jo", "Doe, John", "Doe, Jane"
remove "Doe, Jane" from array to return "Bloggs, Jo","Doe, John"

First you say you want to remove values from an array, then you don't use
a JavaScript Array object at all. That doesn't make much sense to me. If
you want to remove items from an array, then remove items from an array:

<script type="text/javascript">
var theArray = [ 1,2,2,5,7,12,15,21 ];

var theNewArray = removeItems(theArray, 2);
alert(theNewArray.join(", "));

function removeItems(array, item) {
var i = 0;
while (i < array.length) {
if (array == item) {
array.splice(i, 1);
} else {
i++;
}
}
return array;
}
</script>

But, you say to me, "I don't have an array like that". No problem, say
you have the items in a comma-delimited string as original shown:

var theValues = "1,2,2,5,7,12,15,21";
var theArray = theValues.split(/,/);

Doing it for names would work just as well:

var theNewArray = (theNamesArray, "Doe, John");

The only problem would be turning your comma-delimited list of names into
an array. "'Doe, John', 'Smith, Joe'" couldn't be turned into an array by
.split(/,/). There are a number of solutions to this, however the easiest
would be to use another delimiter (one that is unlikely to appear as part
of a person's name in the original string):

var theNames = "'Doe, John'@#!'Smith, Joe'@#!'Jones, Mary'";
var theNamesArray = theNames.split(/@#!/);

Better still, store the first and last names as two properties of an
object, then store that object in the array.


--
| Grant Wagner <[email protected]>

* Client-side Javascript and Netscape 4 DOM Reference available at:
* http://devedge.netscape.com/library/manuals/2000/javascript/1.3/reference/frames.html
* Internet Explorer DOM Reference available at:
* http://msdn.microsoft.com/workshop/author/dhtml/reference/dhtml_reference_entry.asp
* Netscape 6/7 DOM Reference available at:
* http://www.mozilla.org/docs/dom/domref/
* Tips for upgrading JavaScript for Netscape 6/7 and Mozilla
* http://www.mozilla.org/docs/web-developer/upgrade_2.html
 
S

Sam Collett

It only seems to remove the first item in the array (using the
prototype function), but using the removeItems function it performs as
expected.

e.g.

original array:[17,2,5,675]

remove array:[17,2]

resulting array:[2,5,675]

Only the first item (17) seems to be removed from the array.

Do both arrays need to be sorted, and if so how would I go about doing
that?

Grant Wagner said:
Actually, given your initial variables:

var theArray = [ 1,2,2,5,7,12,15,21 ];
var toRemove = [ 1,7 ]
var theNewArray = removeItems(theArray, toRemove);

The resulting array should be 2,2,5,12,15,21 not 1,5,12,15,21

Anyway, use nested loops. Just repeat the original code for each value passed in:

<script type="text/javascript">
var theArray = [ 1,2,2,5,7,12,15,21 ];
var toRemove = [ 1,7 ];
var theNewArray = removeItems(theArray, toRemove);
alert(theNewArray);

function removeItems(originalArray, itemsToRemove) {
var j;
for (var i = 0; i < itemsToRemove.length; i++) {
j = 0;
while (j < originalArray.length) {
if (originalArray[j] == itemsToRemove) {
originalArray.splice(j, 1);
} else {
j++;
}
}
}
return originalArray;
}
</script>

Actually, I'd make removeItems() a method of the Array object:

Array.prototype.removeItems = function(itemsToRemove) {
var j;
for (var i = 0; i < itemsToRemove.length; i++) {
j = 0;
while (j < this.length) {
if (this[j] == itemsToRemove) {
this.splice(j, 1);
} else {
j++;
}
}
}
}
theArray.removeItems(toRemove);
alert(theArray);

Note, this only works for comparable data types (Number, String). If the contents of the array are a more
complex object (such as another Array), then you'll need a method that allows you to evaluate their equality
(== won't do it).

I hope I get a good mark from your instructor for this.


Sam said:
I wasn't sure how to do it using the array object so thought that
using regular expressions would be the solution (i.e. converting the
array to a string and then back into an array after performing the
removal)

Now that you go through it though it seems as though I didn't think of
the obvious (looping though the array and splicing it when the item
was found).

The next step is to try to remove an array of items from the original
array.

e.g.
var theArray = [ 1,2,2,5,7,12,15,21 ];
var toRemove = [ 1,7 ]
var theNewArray = removeItems(theArray, toRemove);

returns 1,5,12,15,21

Would it be possible to do a check to see if the second parameter
(toRemove) is an array or a string, performing a loop on the toRemove
if it is an array?

Maybe it would be simpler to do a nested loop in the function
(converting toRemove to an array, even if the supplied value is a
number or a string)?

Thanks for the help

Grant Wagner said:
Sam Collett wrote:

How do I remove an item with a specified value from an array?

i.e. array values 1,2,2,5,7,12,15,21

remove 2 from array would return
1,5,7,12,15,21

(12 and 21 are NOT removed, duplicates are also removed)

So far I have (val is value, ar is array, returns new array):

function removeFromArray(val, ar){
s = String(ar)
// remove if not first item (global search)
reRemove = new RegExp(","+val,"g")
s = s.replace(reRemove,"")
// remove if at start of array
reRemove = new RegExp("^"+val+",")
s = s.replace(reRemove,"")
// remove if only item
reRemove = new RegExp("^"+val+"$")
s = s.replace(reRemove,"")
return new Array(s)
}

However this seems to return 1,5,7,12,151 (the 151 is a result of the
',2' being removed from the '15,21' part of the array)

How would I modify this to get it to work properly (maybe as one
regular expression - broken down and explained though)?

Also I want it to work with strings as well (possibly containing
commas)

i.e.

array = "Bloggs, Jo", "Doe, John", "Doe, Jane"
remove "Doe, Jane" from array to return "Bloggs, Jo","Doe, John"

First you say you want to remove values from an array, then you don't use
a JavaScript Array object at all. That doesn't make much sense to me. If
you want to remove items from an array, then remove items from an array:

<script type="text/javascript">
var theArray = [ 1,2,2,5,7,12,15,21 ];

var theNewArray = removeItems(theArray, 2);
alert(theNewArray.join(", "));

function removeItems(array, item) {
var i = 0;
while (i < array.length) {
if (array == item) {
array.splice(i, 1);
} else {
i++;
}
}
return array;
}
</script>

But, you say to me, "I don't have an array like that". No problem, say
you have the items in a comma-delimited string as original shown:

var theValues = "1,2,2,5,7,12,15,21";
var theArray = theValues.split(/,/);

Doing it for names would work just as well:

var theNewArray = (theNamesArray, "Doe, John");

The only problem would be turning your comma-delimited list of names into
an array. "'Doe, John', 'Smith, Joe'" couldn't be turned into an array by
.split(/,/). There are a number of solutions to this, however the easiest
would be to use another delimiter (one that is unlikely to appear as part
of a person's name in the original string):

var theNames = "'Doe, John'@#!'Smith, Joe'@#!'Jones, Mary'";
var theNamesArray = theNames.split(/@#!/);

Better still, store the first and last names as two properties of an
object, then store that object in the array.


--
| Grant Wagner <[email protected]>

* Client-side Javascript and Netscape 4 DOM Reference available at:
* http://devedge.netscape.com/library/manuals/2000/javascript/1.3/reference/frames.html
* Internet Explorer DOM Reference available at:
* http://msdn.microsoft.com/workshop/author/dhtml/reference/dhtml_reference_entry.asp
* Netscape 6/7 DOM Reference available at:
* http://www.mozilla.org/docs/dom/domref/
* Tips for upgrading JavaScript for Netscape 6/7 and Mozilla
* http://www.mozilla.org/docs/web-developer/upgrade_2.html
 
D

Dr John Stockton

JRS: In article <[email protected]>, seen
in news:comp.lang.javascript said:
The next step is to try to remove an array of items from the original
array.


There are two approaches.

The first is to loop through toRemove, with an inner loop of theArray.
The second is to loop through theArray, with an inner loop of toRemove.

IMHO, the first, potentially, has greater overheads than the second.

var theArray = [ 1,2,2,5,7,12,15,21 ]
var toRemove = [ 1,7 ]
var theNewArray = []

n = 0
for (j = 0 ; j < theArray.length ; j++) {
X = theArray[j] ; Wanted = true
for (k = 0 ; k < toRemove.length ; k++) {
if (X == toRemove[k]) { Wanted = false ; break } }
if (Wanted) theNewArray[n++] = X
}

To remove from the original array as actually asked, remove "New", and
finally do
theArray.length = n

Note that .splice() is not needed.

Certain optimisations can be made if the arrays are known to be sorted;
increase the initial value of k so as not to test for values which can
no longer occur, and cache the result of the k loop for re-use if X is
unchanged next time.
 
G

Grant Wagner

Don't know what to tell you, I ran the following code in IE6SP1, Mozilla 1.5b, Netscape 4.78 and Opera 7.11 and
they all generated [5, 675]:

var theArray = [17,2,5,675];
var toRemove = [17,2];
// var toRemove = 5;
Array.prototype.removeItems = function(itemsToRemove) {

if (!/Array/.test(itemsToRemove.constructor)) {
itemsToRemove = [ itemsToRemove ];
}

var j;
for (var i = 0; i < itemsToRemove.length; i++) {
j = 0;
while (j < this.length) {
if (this[j] == itemsToRemove) {
this.splice(j, 1);
} else {
j++;
}
}
}
}
theArray.removeItems(toRemove);
alert(theArray);

There may be differences in the way Array.splice() acts in ASP and the way it's implemented in client-side
JavaScript on the tested browsers. The arrays shouldn't need to be in any particular order for the code to work.

Note I've also included some code requested by Greg that tests the removal parameter, so the method can now remove
a single value or an array. It would be trival to also add functionality to allow: Array.removeItems(17, 2); in
addition to Array.removeItems([17, 2]); and Array.removeItems(5);

Sam said:
It only seems to remove the first item in the array (using the
prototype function), but using the removeItems function it performs as
expected.

e.g.

original array:[17,2,5,675]

remove array:[17,2]

resulting array:[2,5,675]

Only the first item (17) seems to be removed from the array.

Do both arrays need to be sorted, and if so how would I go about doing
that?

Grant Wagner said:
Actually, given your initial variables:

var theArray = [ 1,2,2,5,7,12,15,21 ];
var toRemove = [ 1,7 ]
var theNewArray = removeItems(theArray, toRemove);

The resulting array should be 2,2,5,12,15,21 not 1,5,12,15,21

Anyway, use nested loops. Just repeat the original code for each value passed in:

<script type="text/javascript">
var theArray = [ 1,2,2,5,7,12,15,21 ];
var toRemove = [ 1,7 ];
var theNewArray = removeItems(theArray, toRemove);
alert(theNewArray);

function removeItems(originalArray, itemsToRemove) {
var j;
for (var i = 0; i < itemsToRemove.length; i++) {
j = 0;
while (j < originalArray.length) {
if (originalArray[j] == itemsToRemove) {
originalArray.splice(j, 1);
} else {
j++;
}
}
}
return originalArray;
}
</script>

Actually, I'd make removeItems() a method of the Array object:

Array.prototype.removeItems = function(itemsToRemove) {
var j;
for (var i = 0; i < itemsToRemove.length; i++) {
j = 0;
while (j < this.length) {
if (this[j] == itemsToRemove) {
this.splice(j, 1);
} else {
j++;
}
}
}
}
theArray.removeItems(toRemove);
alert(theArray);


--
| Grant Wagner <[email protected]>

* Client-side Javascript and Netscape 4 DOM Reference available at:
* http://devedge.netscape.com/library/manuals/2000/javascript/1.3/reference/frames.html
* Internet Explorer DOM Reference available at:
* http://msdn.microsoft.com/workshop/author/dhtml/reference/dhtml_reference_entry.asp
* Netscape 6/7 DOM Reference available at:
* http://www.mozilla.org/docs/dom/domref/
* Tips for upgrading JavaScript for Netscape 6/7 and Mozilla
* http://www.mozilla.org/docs/web-developer/upgrade_2.html
 
D

Dr John Stockton

JRS: In article <[email protected]>, seen in
There are two approaches.

The first is to loop through toRemove, with an inner loop of theArray.
The second is to loop through theArray, with an inner loop of toRemove.

IMHO, the first, potentially, has greater overheads than the second.

var theArray = [ 1,2,2,5,7,12,15,21 ]
var toRemove = [ 1,7 ]
var theNewArray = []

n = 0
for (j = 0 ; j < theArray.length ; j++) {
X = theArray[j] ; Wanted = true
for (k = 0 ; k < toRemove.length ; k++) {
if (X == toRemove[k]) { Wanted = false ; break } }
if (Wanted) theNewArray[n++] = X
}

To remove from the original array as actually asked, remove "New", and
finally do
theArray.length = n

Moreover, in that the second approach, the visible inner loop (executed
for each element of the original array) can be removed by using an
initial loop executed once. AIUI, a bad Javascript implementation will
do the inner loop internally (which should be faster); a good one will
use a more effective search. The speed of the revised method will only
be minimally affected by duplicates in toRemove.

var theArray = [ 1,2,2,5,7,12,15,21 ]
var toRemove = [ 1,7 ]
var theNewArray = []

var Delenda = []
var U // Undefined value

for (j = 0 ; j < toRemove.length ; j++ ) Delenda[toRemove[j]] = true
n = 0
for (j = 0 ; j < theArray.length ; j++) {
X = theArray[j]
if (Delenda[X] === U) theNewArray[n++] = X
}



or, simplifying, ...

var Delenda = [], j, n = 0, T, U // Undefined value

for (j = 0 ; j < toRemove.length ; j++ )
Delenda[toRemove[j]] = true // or 0 !

for (j = 0 ; j < theArray.length ; j++ )
if ( Delenda[ T = theArray[j] ] === U ) theNewArray[n++] = T



There is no need for theArray or toRemove to be ordered, and order is
preserved; the elements do not need to be numeric.
 
S

Sam Collett

I am using a recordset with the original array in a field.

The removal array is from a series of checkboxes on a form (which is
also from the same field ion the recordset, so the order is the same).

I got the values using String(Request.Form("items")).split(",")

This returns values which include spaces (e.g. [17, 2]) which does not
compare properly for anything but the first value (17)

The solution was to use .split(", "). This suggests that forms submit
a series of values (e.g. from checkboxes) deliminated by ", " so I
have to take into account the space as well.

Now everthing is working as intended.

Grant Wagner said:
Don't know what to tell you, I ran the following code in IE6SP1, Mozilla 1.5b, Netscape 4.78 and Opera 7.11 and
they all generated [5, 675]:

var theArray = [17,2,5,675];
var toRemove = [17,2];
// var toRemove = 5;
Array.prototype.removeItems = function(itemsToRemove) {

if (!/Array/.test(itemsToRemove.constructor)) {
itemsToRemove = [ itemsToRemove ];
}

var j;
for (var i = 0; i < itemsToRemove.length; i++) {
j = 0;
while (j < this.length) {
if (this[j] == itemsToRemove) {
this.splice(j, 1);
} else {
j++;
}
}
}
}
theArray.removeItems(toRemove);
alert(theArray);

There may be differences in the way Array.splice() acts in ASP and the way it's implemented in client-side
JavaScript on the tested browsers. The arrays shouldn't need to be in any particular order for the code to work.

Note I've also included some code requested by Greg that tests the removal parameter, so the method can now remove
a single value or an array. It would be trival to also add functionality to allow: Array.removeItems(17, 2); in
addition to Array.removeItems([17, 2]); and Array.removeItems(5);

Sam said:
It only seems to remove the first item in the array (using the
prototype function), but using the removeItems function it performs as
expected.

e.g.

original array:[17,2,5,675]

remove array:[17,2]

resulting array:[2,5,675]

Only the first item (17) seems to be removed from the array.

Do both arrays need to be sorted, and if so how would I go about doing
that?

Grant Wagner said:
Actually, given your initial variables:

var theArray = [ 1,2,2,5,7,12,15,21 ];
var toRemove = [ 1,7 ]
var theNewArray = removeItems(theArray, toRemove);

The resulting array should be 2,2,5,12,15,21 not 1,5,12,15,21

Anyway, use nested loops. Just repeat the original code for each value passed in:

<script type="text/javascript">
var theArray = [ 1,2,2,5,7,12,15,21 ];
var toRemove = [ 1,7 ];
var theNewArray = removeItems(theArray, toRemove);
alert(theNewArray);

function removeItems(originalArray, itemsToRemove) {
var j;
for (var i = 0; i < itemsToRemove.length; i++) {
j = 0;
while (j < originalArray.length) {
if (originalArray[j] == itemsToRemove) {
originalArray.splice(j, 1);
} else {
j++;
}
}
}
return originalArray;
}
</script>

Actually, I'd make removeItems() a method of the Array object:

Array.prototype.removeItems = function(itemsToRemove) {
var j;
for (var i = 0; i < itemsToRemove.length; i++) {
j = 0;
while (j < this.length) {
if (this[j] == itemsToRemove) {
this.splice(j, 1);
} else {
j++;
}
}
}
}
theArray.removeItems(toRemove);
alert(theArray);


--
| Grant Wagner <[email protected]>

* Client-side Javascript and Netscape 4 DOM Reference available at:
* http://devedge.netscape.com/library/manuals/2000/javascript/1.3/reference/frames.html
* Internet Explorer DOM Reference available at:
* http://msdn.microsoft.com/workshop/author/dhtml/reference/dhtml_reference_entry.asp
* Netscape 6/7 DOM Reference available at:
* http://www.mozilla.org/docs/dom/domref/
* Tips for upgrading JavaScript for Netscape 6/7 and Mozilla
* http://www.mozilla.org/docs/web-developer/upgrade_2.html
 

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,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top