If value is in a list

M

Mike

I have a list of numbers, e.g., (1,3,4,5,8,16,20), and am trying to
create a simple IF statement to see if the value is in that list. Is
there an easier or more efficient way, than the sample code below, to
do it?

=====

<script type="text/javascript">
num = 2;
list = [1,3,4,5,8,16,20];
if(isInList( num, list )) {
alert("It's there!");
} else {
alert("It's NOT there!");
}

function isInList( num, list ) {
// List is an Array()
result = false;
for(i in list) {
if(num == list) { result = true }
}
return result
}
</script>
 
T

Tom Cole

I have a list of numbers, e.g., (1,3,4,5,8,16,20), and am trying to
create a simple IF statement to see if the value is in that list. Is
there an easier or more efficient way, than the sample code below, to
do it?

=====

<script type="text/javascript">
num = 2;
list = [1,3,4,5,8,16,20];
if(isInList( num, list )) {
alert("It's there!");} else {

alert("It's NOT there!");

}

function isInList( num, list ) {
// List is an Array()
result = false;
for(i in list) {
if(num == list) { result = true }
}
return result}

</script>


What about alert(num in list);
 
M

Mike

What about alert(num in list);- Hide quoted text -

Yes, that would work, but I'm actually concerned about the isInList
function. I imagine there's some way to avoid the whole for(i in
list) routine. For example, is there a way to do this:

function isInList( number, list ) {
if(number == anyElementIn( list ) { return true } else { return
false }
}

is there some built in javascript method that will check a value
against any value in an Array?

Thanks!

Mike
 
T

Tom Cole

Yes, that would work, but I'm actually concerned about the isInList
function. I imagine there's some way to avoid the whole for(i in
list) routine. For example, is there a way to do this:

function isInList( number, list ) {
if(number == anyElementIn( list ) { return true } else { return
false }

}

is there some built in javascript method that will check a value
against any value in an Array?

Thanks!

Mike

I've looked around as I'm not aware of one. The best I can come up
with is:

function doCheck(value, array) {
for (var i = 0; i < array.length; i++) {
if (array == value) {
return true;
}
}
return false;
}

This method returns immediately upon a success, rather than looping
through the entire array every time as your first example did.
 
P

Peroli

Yes, that would work, but I'm actually concerned about the isInList
function. I imagine there's some way to avoid the whole for(i in
list) routine. For example, is there a way to do this:

function isInList( number, list ) {
if(number == anyElementIn( list ) { return true } else { return
false }

}

is there some built in javascript method that will check a value
against any value in an Array?

Thanks!

Mike

Mike,
You can use "indexOf" (Javascript 1.6, so won't work in IE) method
on an array instead. But its performance differs from browser to
browser.
"num in list" is faster in Firefox, but slower in Safari.


--- script ---

<html>
<head>
<title>Benchmark</title>
</head>
<body>
<form id="test_form">
<input type="button" value="Benchmark" onclick="benchmark()">
</form>
<span id="result" />
<script type="text/javascript">
function benchmark() {
var a = [1,3,4,5,8,16,20];
var d = new Date();
for(var i=0; i<100000; i++) {
var a1 = a.indexOf(8);
}
var t1 = (new Date()) - d;
d = new Date();
for(var i=0; i<100000; i++) {
var a1 = 8 in a;
}
var t2 = (new Date()) - d;
document.getElementById('result').innerHTML = "indexOf:" + t1 +
'<br />in:' + t2;
}
</script>
</body>
</html>

-- Peroli Sivaprakasam
 
P

Paul Lautman

Mike said:
Yes, that would work, but I'm actually concerned about the isInList
function. I imagine there's some way to avoid the whole for(i in
list) routine. For example, is there a way to do this:

function isInList( number, list ) {
if(number == anyElementIn( list ) { return true } else { return
false }
}

is there some built in javascript method that will check a value
against any value in an Array?

Thanks!

Mike

(','+list.toString()+',').indexOf(','+num+',')

If IE had implemeneted it properly you'd only need list.indexOf(num)
 
T

Tom Cole

(','+list.toString()+',').indexOf(','+num+',')

If IE had implemeneted it properly you'd only need list.indexOf(num)- Hidequoted text -

- Show quoted text -

You could also use RegExp:

function isInArray(value, array) {
return (new RegExp('^(' + array.join('|') + ')$').test(value));
}
 
P

Paul Lautman

Tom said:
You could also use RegExp:

function isInArray(value, array) {
return (new RegExp('^(' + array.join('|') + ')$').test(value));
}

I could, but I am not the one asking for help, so I'm not likely to.
 
T

Thomas 'PointedEars' Lahn

Mike said:
I have a list of numbers, e.g., (1,3,4,5,8,16,20), and am trying to
create a simple IF statement to see if the value is in that list. Is
there an easier or more efficient way, than the sample code below, to
do it?

=====

<script type="text/javascript">
num = 2;
list = [1,3,4,5,8,16,20];

You should declare all your identifiers. For those which should be
variables, e.g.

var num = 2;
if(isInList( num, list )) {
alert("It's there!");
} else {
alert("It's NOT there!");
}

function isInList( num, list ) {
// List is an Array()
result = false;

There. You create a *globally* available property, if that. Bad.
for(i in list) {
if(num == list) { result = true }
}
return result
}


This would work for numeric values, but it would be inefficient, and
error-prone. Note a) that you can stop looping once you have found an item,
b) that `==' performs implicit type conversion, and c) that for..in
iteration is not equivalent to C-style `for' iteration (it iterates over the
list of all enumerable properties, not just those designating
array/collection elements). Use instead

/**
* @param number num
* @param Array list
*/
function inArray(num, list)
{
var result = false;

for (var i = list.length; i--;)
{
if (list === num)
{
result = true;
break;
}
}

return result;
}

JavaScript 1.6+ also supports a native method:

list.indexOf(num) >= 0

http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf


PoinedEars
 
T

Thomas 'PointedEars' Lahn

Mike said:
What about alert(num in list);- Hide quoted text -

Yes, that would work, [...]

No, it would not. This expression evaluates to `true' if the value of
`num' is the name of a property of the object referred to by `list'. So

2 in [1, 2]

evaluates to `false' even though `2' is clearly an element in `[1, 2]':

[1, 2][2]

or equally

[1, 2]["2"]

is undefined as there is no third element (with index 2).

Therefore, what could work is to use the array elements as property names
for an Object object, and then apply the `in' operation on the latter:

var list = [1, 2];
var o = {};

for (var i = list.length; i--;)
{
o[list] = true;
}

// true
2 in o

Note that the `in' operation, unlike for..in iteration, requires JavaScript
1.4, JScript 5.0, ECMAScript Ed. 3.

See also http://PointedEars.de/es-matrix/


Please don't remove the attribution line next time.


PointedEars
 
T

Thomas 'PointedEars' Lahn

Paul said:
Mike said:
[...] For example, is there a way to do this:

function isInList( number, list ) {
if(number == anyElementIn( list ) { return true } else { return
false }
}

is there some built in javascript method that will check a value
against any value in an Array?
[...]

(','+list.toString()+',').indexOf(','+num+',')

Good idea, but this really only works for arrays that have serializable
values as elements. One can implement general serialization by overwriting
Object.prototype.toString() (without breaking for..in iteration), but only
enumerable properties and non-enumerable properties of which the names are
known can be included.
If IE had implemeneted it properly you'd only need list.indexOf(num)

Array.prototype.indexOf() is a proprietary JavaScript 1.6+ feature not
specified in ECMAScript, so it is pointless to say that IE did not implement
it properly. It is even more pointless because it would not have to be
IE/MSHTML but Microsoft JScript to implement it.

Please trim your quotes, especially don't quote signatures.


PointedEars
 
T

Thomas 'PointedEars' Lahn

Paul said:
(','+list.toString()+',').indexOf(','+num+',')

BTW,

(',' + list + ',').indexOf(',' + num + ',')

suffices as string concatenation implicitly calls
String.prototype.toString() on its non-string operands.


PointedEars
 
T

Thadeu de Paula

BTW,

(',' + list + ',').indexOf(',' + num + ',')

suffices as string concatenation implicitly calls
String.prototype.toString() on its non-string operands.

PointedEars
--
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
-- Richard Cornford, cljs, <[email protected]>

People...
lest use the things for the ends that they was created!
What's the problem using for?! Usign RegExp... you'll need to turn the
list into a string... it's an unnecessary step.

function arrayMember (value,list) {
for (var i in list) if (list===value)
return i;
break;
};
return false;
}

This is good for biiiiiiigger lists, once it break! :D
And you will have what can be a useful info: the index!

---
About prototype, scriptaculous, jquery, etc...
I don't like to use them... I prefer do little specific libs and put
on my code when necessary...
I dislike to use excessive object abbreviations... but, I think, even
with these I can learn something.

That's the spirit!
 
T

Thadeu de Paula

(',' + list + ',').indexOf(',' + num + ',')
suffices as string concatenation implicitly calls
String.prototype.toString() on its non-string operands.
PointedEars
--
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
-- Richard Cornford, cljs, <[email protected]>

People...
lest use the things for the ends that they was created!
What's the problem using for?! Usign RegExp... you'll need to turn the
list into a string... it's an unnecessary step.

function arrayMember (value,list) {
for (var i in list) if (list===value)
return i;
break;
};
return false;

}

This is good for biiiiiiigger lists, once it break! :D
And you will have what can be a useful info: the index!

---
About prototype, scriptaculous, jquery, etc...
I don't like to use them... I prefer do little specific libs and put
on my code when necessary...
I dislike to use excessive object abbreviations... but, I think, even
with these I can learn something.

That's the spirit!


Oppps... there something wrong.. sorry!

function arrayMember (value,list) {
for (var i in list) if (list===value) {
return i;
break;
};
return false;
};
 
D

Dr J R Stockton

In comp.lang.javascript message <074fe8ad-e977-4925-9aef-8926efc78b31@8g
2000hse.googlegroups.com>, Tue, 22 Apr 2008 11:43:14, Mike
I have a list of numbers, e.g., (1,3,4,5,8,16,20), and am trying to
create a simple IF statement to see if the value is in that list. Is
there an easier or more efficient way, than the sample code below, to
do it?

Yes, undoubtedly.

If the list is unordered, a full scan is unavoidable; it should be
(assuming the list is in an Array) scanned with a while loop scanning
down only until the value is found.

If the list is ordered, I guess that a binary chop search **might** be
more efficient, depending on the JavaScript implementation.

If the list is to be searched many times, and is not too sparse, it
could well be worth inverting it with, say,
A = [] ; J = L.length ; while (J--) A[L[J]] = 1
since your test for value V then becomes just
if (A[V])
and the internal code for that ought to be efficient. Test it.

Results may depend on how sparse the original list is, as well as how
long; there could be a considerable difference in speed between the
lists (0, 3, 6, 9) and (0, 3e3, 6e6, 9e9).

If the list is a String of separated numbers, then use IndexOf or a
RegExp, remembering that the search must, unless the numbers are padded
to constant length, seek also the separators. If the search is to be
done many times, sort the entries, split the string, and look only in
the right part - when seeking information on Gnus in a large
encyclopaedia, one first selects the volumes containing the G-words, and
does not read about Aardvarks or Eels or Oxen /en route/.

It's a good idea to read the newsgroup c.l.j and its FAQ. See below.
 
T

Tom Cole

In comp.lang.javascript message <074fe8ad-e977-4925-9aef-8926efc78b31@8g
2000hse.googlegroups.com>, Tue, 22 Apr 2008 11:43:14, Mike
I have a list of numbers, e.g., (1,3,4,5,8,16,20), and am trying to
create a simple IF statement to see if the value is in that list.  Is
there an easier or more efficient way, than the sample code below, to
do it?

Yes, undoubtedly.

If the list is unordered, a full scan is unavoidable; it should be
(assuming the list is in an Array) scanned with a while loop scanning
down only until the value is found.

If the list is ordered, I guess that a binary chop search **might** be
more efficient, depending on the JavaScript implementation.

If the list is to be searched many times, and is not too sparse, it
could well be worth inverting it with, say,
  A = [] ; J = L.length ; while (J--) A[L[J]] = 1
since your test for value V then becomes just
  if (A[V])
and the internal code for that ought to be efficient.  Test it.

Results may depend on how sparse the original list is, as well as how
long; there could be a considerable difference in speed between the
lists (0, 3, 6, 9) and (0, 3e3, 6e6, 9e9).

If the list is a String of separated numbers, then use IndexOf or a
RegExp, remembering that the search must, unless the numbers are padded
to constant length, seek also the separators.  If the search is to be
done many times, sort the entries, split the string, and look only in
the right part - when seeking information on Gnus in a large
encyclopaedia, one first selects the volumes containing the G-words, and
does not read about Aardvarks or Eels or Oxen /en route/.

It's a good idea to read the newsgroup c.l.j and its FAQ.  See below.

--
 (c) John Stockton, nr London UK.   [email protected]     IE7 FF2 Op9 Sf3
 FAQ <URL:http://www.jibbering.com/faq/index.html>.
 <URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
 <URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.

Just to toss another option out there...what about RegExp?

function doCheck(value, array) {
return (new RegExp('^(' + array.join('|') + ')$').test(value));
}

Send it the value to look for and the array of values...
 
T

Thomas 'PointedEars' Lahn

Tom said:
Just to toss another option out there...what about RegExp?

Is there a point in your repeating your suggestion ...
function doCheck(value, array) {
return (new RegExp('^(' + array.join('|') + ')$').test(value));
}

.... already made in
Send it the value to look for and the array of values...

See <
And please trim your quotes.


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
474,142
Messages
2,570,819
Members
47,367
Latest member
mahdiharooniir

Latest Threads

Top