Iterating sparse arrays

  • Thread starter Christopher Benson-Manica
  • Start date
R

rh

Michael said:
[snip]

So the question, it seems to me, is whether you can reliably do
lookup.

Yes, provided that supporting code is used to perform it. However, I'd
argue that this necessity clearly means that "associative arrays" cannot
be deemed part of the language.

"deemed part of the language" is too strong. It has more to do with
availability of very useful functionality that is relatively
widely-known as a part of basic computing.

In the context of the language itself, the volume of material that you
are producing in expounding upon the absence of "associative arrays"
from the language, is really testimony to tremendous missed opportunity
of having string-based associative arrays native to the language --
there should be, but there is not, a way to turn off an object's (at
the very least an Object object's) prototype chain search.
[snip]
The following demonstrates the battle you're waging is likely lost:

I'm certain that there is a number of sites masquerading as references
which "teach" this topic in a misleading way. That in itself would already
signal the battle is lost.

But there are many that talk about "Objects as Associative Arrays"
(including early versions of Javascript: The Definitive Guide -- I
don't know about later editions). They don't say objects are
"associative arrays" -- they speak of their use as such.

It's true, however, that rarely is appropriate qualification on use
(the pitfalls) is given.
I wouldn't say that's particularly devastating.

There was no intention that it be devastating. It was just a reminder
that it can be difficult to ride a high horse, when the hordes
surround.
It even mentions that a
prototype will interfere affect the properties available, however it would
probably take some careful thinking for the reader to realise what the
implications are.

But perhaps not as much careful thinking for a reader to wade through
the reasons being given for never, ever thinking of Javascript objects
as providing "associative array" functionality. ;-)

Regards,

../rh
 
R

Robert

rh said:
Given that propertyIsEnumerable doesn't venture into the prototype
chain, a hasOwnProperty check would seem to redundant. So my later
suggestion would be to simply replace the hasOwnProperty with a
propertyIsEnumerable check;

I put together a test page. Had a curious result when attempting to set
the __proto__ property of an array and object... Variable not set and
not error message. Strange deal indeed... if I got it right.

Robert

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Associative tests</title>
<script type="text/javascript">

function smallString(myInput)
{
if (typeof myInput == "undefined" )
{ return myInput; }
else
{
var alpha = myInput.toString();
alpha = alpha.split("{")[0];
return alpha;
}
}

function checkArray(myInput)
{
var myDel = typeof myInput == "string"? "'" : " ";
document.write( "<tr>" +
"<td>myArray[" + myDel + myInput + myDel + "]</td>" +
"<td>" + smallString(myArray[myInput]) + "</td>" +
"<td>" +
(myArray.hasOwnProperty?myArray.hasOwnProperty(myInput):"&nbsp;")+
"</td>" +
"<td>" +

(myArray.propertyIsEnumerable?myArray.propertyIsEnumerable(myInput):"&nbs
p;")+
"</td>" +
"<td>" +

(myArray.isPrototypeOf?Array.prototype.propertyIsEnumerable(myInput):"&nb
sp;")+
"</td>" +
"<tr>");
}

function checkObject(myInput)
{
var myDel = typeof myInput == "string"? "'" : " ";
document.write( "<tr>" +
"<td>myObject[" + myDel + myInput + myDel + "]</td>" +
"<td>" + smallString(myObject[myInput]) + "</td>" +
"<td>" +

(myObject.hasOwnProperty?myObject.hasOwnProperty(myInput):"&nbsp;")+
"</td>" +
"<td>" +

(myObject.propertyIsEnumerable?myObject.propertyIsEnumerable(myInput):"&n
bsp;")+
"</td>" +
"<td>" +

(myObject.isPrototypeOf?Object.prototype.propertyIsEnumerable(myInput):"&
nbsp;")+
"</td>" +
"<tr>");
}

</script>
</head>
<body>
<p>See the results of hasOwnProperty, and propertyIsEnumerable
for an <b>Array</b>.
</p>
<table>
<thead>
<th>
variable
</th>
<th>
value<br>trimmed
</th>
<th>
myArray.<br>has<br>Own<br>Property
</th>

<th>myArray.<br>property<br>Is<br>Enumerable
</th>
<th>
Array.<br>prototype.<br>property<br>Is<br>Enumerable
</th>
</thead>
<tbody>
<script type="text/javascript">

var myArray = ['zero'];

myArray[2] = 'thing';
Array.prototype.pi = 3.14159;
myArray['myIndex'] = 'something';

checkArray(2);
checkArray('2');
checkArray('myIndex');
checkArray('pop');
checkArray('toString');
checkArray('pi');
checkArray('noIndex');
checkArray('hasOwnProperty');
checkArray('__proto__');



</script>
</table>
<br>
<p>
Using join() the data in the array is:
<script type="text/javascript">
document.write(myArray.join());
document.write(" and has " + myArray.length + " elements with numeric
indexes.");
</script>
</p><p>Using in the list in indexes for myArray is:
<script type="text/javascript">
var accum;
var begun = false;
for (var i in myArray)
{
if ( begun == true )
{ accum += ", " + i }
else
{ accum = i;
begun = true; }
}
document.write(accum);
</script>
</p>
<br>
<p>See the results of hasOwnProperty, and propertyIsEnumerable
for an <b>Object</b>.
</p>
<table>
<thead>
<th>
variable
</th>
<th>
value<br>trimmed
</th>
<th>
myArray.<br>has<br>Own<br>Property
</th>

<th>myArray.<br>property<br>Is<br>Enumerable
</th>
<th>
Array.<br>prototype.<br>property<br>Is<br>Enumerable
</th>
</thead>
<script type="text/javascript">
var myObject = {'declared': 'data'};

myObject[2] = 'thing';
Object.prototype.pi = 3.14159;
myObject['myIndex'] = 'something';

checkObject(2);
checkObject('2');
checkObject('myIndex');
checkObject('declared');
checkObject('pop');
checkObject('toString');
checkObject('toLocaleString');
checkObject('pi');
checkObject('noIndex');
checkObject('hasOwnProperty');
checkObject('__proto__');



</script>
</table>
<br>
<p>Using in the list in indexes for myObject is:
<script type="text/javascript">
var accum;
var begun = false;
for (var i in myObject)
{
if ( begun == true )
{ accum += ", " + i }
else
{ accum = i;
begun = true; }
}
document.write(accum);
</script>
</p>


<p>Assign new values to <b>myArray</b>.
<table>
<thead>
<th>
variable
</th>
<th>
value<br>trimmed
</th>
<th>
myArray.<br>has<br>Own<br>Property
</th>

<th>myArray.<br>property<br>Is<br>Enumerable
</th>
<th>
Array.<br>prototype.<br>property<br>Is<br>Enumerable
</th>
</thead>
<tbody>
<script type="text/javascript">

myArray['pop'] = 'something';
myArray['__proto__'] = "my thing";

checkArray('pop');
checkArray('__proto__');
</script>
</table>
<p>
Using join() the data in the array is:
<script type="text/javascript">
document.write(myArray.join());
document.write(" and has " + myArray.length + " elements with numeric
indexes.");
</script>
</p><p>Using in the list in indexes for myArray is:
<script type="text/javascript">
var accum;
var begun = false;
for (var i in myArray)
{
if ( begun == true )
{ accum += ", " + i }
else
{ accum = i;
begun = true; }
}
document.write(accum);
</script>
</p>
<br>
<br>
<p>Assign some more values to <b>myObject</b>.
</p>
<table>
<thead>
<th>
variable
</th>
<th>
value<br>trimmed
</th>
<th>
myArray.<br>has<br>Own<br>Property
</th>

<th>myArray.<br>property<br>Is<br>Enumerable
</th>
<th>
Array.<br>prototype.<br>property<br>Is<br>Enumerable
</th>
</thead>
<script type="text/javascript">


myObject['toLocaleString'] = 'something';
myObject['__proto__'] = 'my something';


checkObject('toLocaleString');
checkObject('__proto__');



</script>
</table>
<br>
<p>Using in the list in indexes for myObject is:
<script type="text/javascript">
var accum;
var begun = false;
for (var i in myObject)
{
if ( begun == true )
{ accum += ", " + i }
else
{ accum = i;
begun = true; }
}
document.write(accum);
</script>
</p>

<br>
<p>
<script type="application/x-javascript">
document.write(navigator.userAgent);
</script>
</body>
</html>
 
R

rh

Robert said:
I put together a test page. Had a curious result when attempting to set
the __proto__ property of an array and object... Variable not set and
not error message.

Mentioned that "little" anomaly in an earlier post, although it should
have contained the word "attempt":

'Moreover, if you make an assignment to these properties, no assignment
is made. That makes these properties "special".'
Strange deal indeed... if I got it right.
Yes, unfortunately.

../rh
 
R

Robert

I got the info about __proto__ from your ealier post. Didn't know that
I wouldn't get an error message.

Robert
 
M

Mighty Krell

Douglas Crockford said:
Wrong is wrong even if you do not understand the difference.


You're full of crap. JS allows string indices on purpose. It's quite
intentional, even if you don't like it.

MK
 
R

Richard Cornford

Mighty said:
You're full of crap.
?

JS allows string indices on purpose.

"indices" is a potentially misleading term to use in this context, with
its connotations of numeric indices as used in Arrays.

Javascript supports bracket notation property accessors for a reason,
but that reason is mostly related to accessing the properties of Objects
with dynamically determined property names.
It's quite intentional, even if you don't like it.

There is no implication in Douglas's posts that he doesn't like bracket
notation property accessors. He is impugning the appropriateness of
using an objet specialised as an Array in circumstances where only the
general behaviour of Objects is desired.

Richard.
 
R

Robert

JS allows string indices on purpose.

"indices" is a potentially misleading term to use in this context, with
its connotations of numeric indices as used in Arrays.[/QUOTE]

But we know that javascript allows arrays to have string indexes.

from: http://wombat.doc.ic.ac.uk/foldoc/foldoc.cgi?index
index

(Plural "indices" or "indexes")

1. <programming> A number used to select an element of a list, vector,
array or other sequence. Such indices are nearly always non-negative
integers but see associative array.

2. <database> See inverted index. [Other kinds?]

3. <World-Wide Web> A search engine.

4. <World-Wide Web> A subject index.

4. <jargon> See coefficient of X.

associative array

<programming> An array where the indices are not just integers but may
be arbitrary strings.

awk and its descendants (e.g. Perl) have associative arrays which are
implemented using hash coding.

from: http://en.wikipedia.org/wiki/Indices

In information technology

In computer science, an index is usually used for expressing an nth
element. Indices are usually expressed as integers.

These two definition acknowledge that people are using the term indices
to include non numeric values but these folks are in the minority. It
seems the direction is to use the term indices even if the array allow
string indexes.

I think that interpretive languages blur the distinction between numeric
only indexes to arrays and string based access to data object. The
distinction is more related to a language like C not a language like
Javascript.

I have done a lot a programming in languages with associative arrays as
the underlaying data structure used to access data. It's not a big deal
to me to use string indexes in arrays since I am used to this being the
only way to access the data.
Javascript supports bracket notation property accessors for a reason,
but that reason is mostly related to accessing the properties of Objects
with dynamically determined property names.


There is no implication in Douglas's posts that he doesn't like bracket
notation property accessors. He is impugning the appropriateness of
using an objet specialised as an Array in circumstances where only the
general behaviour of Objects is desired.

This is a little to strong. Douglas objected twice to my earlier posts
when I pointed out that you could have a string index in a Javascript
array.

It seems to me that the underlaying data saving method in Javascript is
an associative array. There are two ways of accessing the data in the
associative array. One in the array syntax and the other the object
syntax.

Considering that array indices are saved as a strings, there seems to be
too much hand waving over how bad it is to use a string as an index with
an array. Also, I associate the bracket notation with array access, so
it is interesting some find it perfectly normal to use bracket notation
with an object but unacceptable to use a string an an index in an array.

Javascript aren't C so let's not apply the C language conventions to
object like arrays in Javascript.

Robert
 
D

Douglas Crockford

It seems to me that the underlaying data saving method in Javascript is
an associative array. There are two ways of accessing the data in the
associative array. One in the array syntax and the other the object
syntax.

The underlying structure is the object. In JavaScript, the object is the
associative array. The JavaScript array is a specialization of the
object with special features for handling numeric subscripts.

The dot notation and subscript notation both work with objects, and
since arrays are, deep down, object, both notations work with arrays, too.

It is possible to use non-numeric subscripts with arrays, but that
usually indicates a lack of understanding. Fortunately, such a lack is
easily remedied. See for example
http://www.crockford.com/javascript/survey.html
 
R

Richard Cornford

Robert said:
But we know that javascript allows arrays to have string
indexes.

What we know is that bracket notation allows the named properties of
Objects to be referenced using expressions that evaluate to results that
are strings, or can be type-converted to strings. We also know that
Arrays are a specialised type of the native ECMAScript object, as are
Functions, Dates, regular expressions and Boolean String and Number
objects. Whether those expressions representing object property names
are indices is a matter of the interpretation of language.
from: http://wombat.doc.ic.ac.uk/foldoc/foldoc.cgi?index
index

(Plural "indices" or "indexes")

1. <programming> A number used to select an element of a
list, vector, array or other sequence. Such indices are nearly
always non-negative integers but see associative array.
associative array

<programming> An array where the indices are not just integers
but may be arbitrary strings.
In computer science, an index is usually used for expressing
an nth element. Indices are usually expressed as integers.

So we have a term that would normally refer to an integer number, but
may less commonly refer to a sequence of characters (or a non-integer
number). That is precisely why I proposed that the term has connotations
of numeric indices, and so is a potentially misleading term to apply to
the accessing of the named properties of objects.
These two definition acknowledge that people are using
the term indices to include non numeric values but these
folks are in the minority.

And the people who read descriptions of javascript property accessors
couched in terms of 'indices' and assume that their use in the context
of an Array will provide some sort of - length - related, or iteration
effect, are also in a minority. But they would still be better off if
the terminology used in explanations made a clear distinction between
the normal behaviour of all native ECMAScript objects and the
specialised behaviour additionally provided by Array objects.
It seems the direction is to use the term indices even if
the array allow string indexes.

In javascript it is not the Array that is 'allowing string indices', it
is the Object that allows the dynamic creation and referencing of named
properties. The Array _adds_ behaviour to an underlying native
ECMAScript object. All Arrays were native ECMAScript objects before they
were Arrays.
I think that interpretive languages blur the distinction
between numeric only indexes to arrays and string based
access to data object. The distinction is more related to
a language like C not a language like Javascript.

The expressions used in bracket notation property accessors are always
type converted to strings so the distinction is blurred, to the point of
there being no apparent distinction. And with unaugmented native
ECMAScript objects there is no distinction at all.

This is a little to strong. Douglas objected twice to my earlier
posts when I pointed out that you could have a string index in a
Javascript array.

It is normal to discourage the promotion of misconceptions on this
group. And this group is a good place to observe which misconceptions
are common, and what factors promote them. Often they arise form
individuals applying expectations gained from other languages to
javascript. Sometimes they follow from inappropriately worded
explanations, and sometimes they follow from misguided examples (or
combinations of these). The relationship between javascript
Objects/Arrays and associative arrays and hashtables in other languages
is frequently the subject of these misconceptions.
It seems to me that the underlaying data saving method
in Javascript is an associative array.

The implementation details are left to the authors of the interpreter to
decide. Some certainly appear to be very hashtable/associative array
like, others betray evidence of list-like implementation.

Considering that array indices are saved as a strings, there
seems to be too much hand waving over how bad it is to use a
string as an index with an array.

The hand waving is not about dynamically creating named properties on
Array objects, it is about promoting the misconception that this has
something to do with the Arrayness of that object, rather than its
underlying Objectness. A misconception that is promoted, at leas in
part, by the use of inappropriate terminology in the context.
Also, I associate the bracket notation with array access,

While in javascript that syntax is actually a direct parallel to dot
notation property accessors. An invaluable facility in a dynamic
language. And there is actually no specialised Array accessing syntax at
all.
so it is interesting some find it perfectly normal to
use bracket notation with an object but unacceptable to
use a string an an index in an array.

Nobody finds it unacceptable to 'use a string to index an array'. What
is unacceptable is using an Array object in a context where an Object
object would facilitate all that is required. The specialised objects
should be reserved for circumstances where the facilities provided by
their specialisation are necessary for the task. An Array object is
specialised for use with integer indexes and interactions using its -
length - property (along with the many integer indexed property
manipulation methods provided on its prototype). If those facilities are
not being used there is no point in having them.
Javascript aren't C so let's not apply the C language
conventions to object like arrays in Javascript.

Who is applying C conventions? An understanding of javascript/ECMAScript
is sufficient to guide its appropriate application.

Richard.
 

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,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top