# Comparing arraies

A

#### Archos

How to know if 2 arraies are equal? I was expecting that it could be
checked so:
var array1 = [1,2,3,4], array2 = [1,2,3,4];
if (array1 === array2) { console.log("array1 and array2 are equal"); }

Since the comparing of strings or integers works:

var a = "2", b = "2";
if (a === b) { console.log("a == b"); }

M

#### Martin Honnen

Archos said:
How to know if 2 arraies are equal? I was expecting that it could be
checked so:
var array1 = [1,2,3,4], array2 = [1,2,3,4];
if (array1 === array2) { console.log("array1 and array2 are equal"); }

Since the comparing of strings or integers works:

var a = "2", b = "2";
if (a === b) { console.log("a == b"); }

No, for objects (and arrays are objects) the identity is checked, no
comparison of properties or elements is done.
So with e.g.

var a1, a2;

a1 = a2 = [1, 2, 3, 4];

a1 == a2

you get true as the two variables hold references to the same array object.

If you want to compare the elements you will need to define and
implement your own comparison function I think

T

#### Thomas 'PointedEars' Lahn

Martin said:
Archos said:
How to know if 2 arraies are equal? I was expecting that it could be
checked so:
var array1 = [1,2,3,4], array2 = [1,2,3,4];
if (array1 === array2) { console.log("array1 and array2 are equal"); }

Since the comparing of strings or integers works:

var a = "2", b = "2";
if (a === b) { console.log("a == b"); }

No, for objects (and arrays are objects) the identity is checked, no
comparison of properties or elements is done.
So with e.g.

var a1, a2;

a1 = a2 = [1, 2, 3, 4];

a1 == a2

you get true as the two variables hold references to the same array
object.

Correct. That example might be confusing, though.
If you want to compare the elements you will need to define and
implement your own comparison function I think

Not necessarily. One way without a custom comparison function that works
for *simple* cases like this is to compare the string representations of the
Array instances, which are (without overwriting the toString() method) the
comma-separated string representations of the corresponding array's
elements:

/* "1,2,3,4" == "1,2,3,4" */
a1.toString() == a2.toString()

or

String(a1) == String(a2)

or

("" + a1) == ("" + a2)

That is, those two arrays are considered equal if the string representations
of their elements are the same and occur in the same order (if we assume
that both instances use the same toString() method).

The caveat is that the string representations of elements can be the same,
although the elements are different. Consider this:

var o = {foo: 'bar'};
var o2 = {bar: 'baz'};

/* "[object Object]" == "[object Object]" */
[o].toString() == [o2].toString()

Instead of the `==' operator, the `===' operator may be used as well, but it
is neither supposed to add efficiency nor would it add expressive power
(both arguments are of the same type), while it certainly reduces the
backwards-compatibility of the entire code.

PointedEars
--
If you get a bunch of authors [â€¦] that state the same "best practices"
in any programming language, then you can bet who is wrong or right...
Not with javascript. Nonsense propagates like wildfire in this field.
-- Richard Cornford, comp.lang.javascript, 2011-11-14

T

#### Thomas 'PointedEars' Lahn

Thomas said:
Instead of the `==' operator, the `===' operator may be used as well, but
it is neither supposed to add efficiency nor would it add expressive power
(both arguments are of the same type), while it certainly reduces the
backwards-compatibility of the entire code.

_Operands_, not arguments. We are not talking about a function, but about
an operator.

PointedEars

D

#### Denis McMahon

Archos said:
How to know if 2 arraies are equal? I was expecting that it could be
checked so:
var array1 = [1,2,3,4], array2 = [1,2,3,4]; if (array1 === array2) {
console.log("array1 and array2 are equal"); }

Since the comparing of strings or integers works:

var a = "2", b = "2";
if (a === b) { console.log("a == b"); }

No, for objects (and arrays are objects) the identity is checked, no
comparison of properties or elements is done. So with e.g.

var a1, a2;

a1 = a2 = [1, 2, 3, 4];

a1 == a2

you get true as the two variables hold references to the same array
object.

If you want to compare the elements you will need to define and
implement your own comparison function I think

It might be easier to compare two vars universally, assuming the JSON
object is available, by:

function are_identical(var1, var2) {
return JSON.stringify(var1) === JSON.stringify(var2);
}

I think this would work for anything that can be stringified by the
JSON.stringify() method.

Rgds

Denis McMahon

M

#### Michael Haufe (TNO)

How to know if 2 arraies are equal? I was expecting that it could be
checked so:
var array1 = [1,2,3,4], array2 = [1,2,3,4];
if (array1 === array2) { console.log("array1 and array2 are equal"); }

Since the comparing of strings or integers works:

var a = "2", b = "2";
if (a === b) { console.log("a == b"); }

Two arrays are equal iff they have equal elements in respective
positions:

var a1 = [1,2,3,4], a2 = [1,2,3,4];

a1.every(function(e,i){ return e === a2}); //true

a1 = a2 = [1, 2, 3, 4];

a1.every(function(e,i){ return e === a2}); //true

var o = {foo: 'bar'}, o2 = {bar: 'baz'};

a1 = [o,o2], a2 = [o2,o];

a1.every(function(e,i){ return e === a2}); //false

a1 = [o,o2], a2 = [o,o2];

a1.every(function(e,i){ return e === a2}); //true

G

#### Gene Wirchenko

On 26 Jan 2012 23:08:55 GMT, Denis McMahon <[email protected]>
wrote:

[snip]
It might be easier to compare two vars universally, assuming the JSON
object is available, by:

function are_identical(var1, var2) {
return JSON.stringify(var1) === JSON.stringify(var2);
}

I think this would work for anything that can be stringified by the
JSON.stringify() method.

Why not just toString()?
if (var1.toString()===var2.toString())

Sincerely,

Gene Wirchenko

D

#### Denis McMahon

On 26 Jan 2012 23:08:55 GMT, Denis McMahon <[email protected]>
wrote:

[snip]
It might be easier to compare two vars universally, assuming the JSON
object is available, by:

function are_identical(var1, var2) {
return JSON.stringify(var1) === JSON.stringify(var2); }

I think this would work for anything that can be stringified by the
JSON.stringify() method.

Why not just toString()?
if (var1.toString()===var2.toString())

var x;
x.fred = 9;
x.jim = 23.654;
x.sue[0] = [15,"mouse",[12,14,5,"BASHER"],543.876];
x.sue[1] = "is x.toString() defined?";

Rgds

Denis McMahon

E

#### Evertjan.

Gene Wirchenko wrote on 27 jan 2012 in comp.lang.javascript:
Why not just toString()?
if (var1.toString()===var2.toString())

This is why not:

var a = [1,2,3,'qwerty'];
var b = ['1,2',3,'qwerty'];

alert(String(a) === String(b)); // wrongly true

alert(a.toString() === b.toString()); // wrongly true

// only if you are certain that '+%%%+=' is not part of the content.
// even then only valid if the array content is only numeric or string

T

#### Thomas 'PointedEars' Lahn

Denis said:
Gene said:
Denis said:
[â€¦]
function are_identical(var1, var2) {
return JSON.stringify(var1) === JSON.stringify(var2); }

I think this would work for anything that can be stringified by the
JSON.stringify() method.

Why not just toString()?
if (var1.toString()===var2.toString())

var x;
x.fred = 9;
x.jim = 23.654;
x.sue[0] = [15,"mouse",[12,14,5,"BASHER"],543.876];
x.sue[1] = "is x.toString() defined?";

This code cannot run (as-is; if `x' was assigned a reference to an object
with a `sue' property before, then it *could* work), and does not constitute
a proof at all.

A useful example showing why toString() does not suffice for all cases is

/* "1,2,3,4" == "1,2,3,4" */
[1, [2, 3], 4].toString() == [[1, 2], [3, 4]].toString()

If the JSON property is unavailable or wrong implemented, it can be
emulated, either by using the implementation from <http://json.org/> or
another object serializer.

PointedEars

M

#### Martin Honnen

Michael said:
How to know if 2 arraies are equal? I was expecting that it could be
checked so:
var array1 = [1,2,3,4], array2 = [1,2,3,4];
if (array1 === array2) { console.log("array1 and array2 are equal"); }

Two arrays are equal iff they have equal elements in respective
positions:

var a1 = [1,2,3,4], a2 = [1,2,3,4];

a1.every(function(e,i){ return e === a2}); //true

I think an additional check that the length of both arrays is the same
is necessary as otherwise solely doing
a1.every(function(e,i){ return e === a2});
with a1 being shorter than a2 might give true for e.g.
a1 = [1, 2, 3];
a2 = [1, 2, 3, 4, 5];
which is likely not intended.

J

#### John G Harris

_Operands_, not arguments. We are not talking about a function, but about
an operator.

Operators are also functions. How else would + be defined?

John

T

#### Thomas 'PointedEars' Lahn

John said:
Operators are also functions. How else would + be defined?

You are confusing functions with algorithms. The subject of discussion here
is the syntax of the programming language, not the implementation of the
syntax.

PointedEars

D

#### Dr J R Stockton

In comp.lang.javascript message <[email protected]>,
Archos said:
How to know if 2 arraies are equal? I was expecting that it could be
checked so:

var array1 = [1,2,3,4], array2 = [1,2,3,4]; if (array1 === array2) {
console.log("array1 and array2 are equal"); }

Since the comparing of strings or integers works:

var a = "2", b = "2";
if (a === b) { console.log("a == b"); }

No, for objects (and arrays are objects) the identity is checked, no
comparison of properties or elements is done. So with e.g.

var a1, a2;

a1 = a2 = [1, 2, 3, 4];

a1 == a2

you get true as the two variables hold references to the same array
object.

If you want to compare the elements you will need to define and
implement your own comparison function I think

It might be easier to compare two vars universally, assuming the JSON
object is available, by:

function are_identical(var1, var2) {
return JSON.stringify(var1) === JSON.stringify(var2);
}

I think this would work for anything that can be stringified by the
JSON.stringify() method.

Observe :
A = new Array(5)
B = new Array(6)
for which A[<anything>] = B[<anything>] = undefined; yet String(B) is
visibly longer than String(A).

Note : JSON.stringify(A) -> [null,null,null,null,null]
so JSON cannot tell a null from an undefined (in FF 9.0.1).

Consider
A = [1, [1, 1], 1]
B = [[1, 1], [1, 1]]
String() gives the same for each, but JSON can tell the difference.

But, in general, enough will be reliably known about the array contents
for String() to be safe.

J

#### John G Harris

You are confusing functions with algorithms. The subject of discussion here
is the syntax of the programming language, not the implementation of the
syntax.

1. The syntax specification calls new a keyword and + a punctuator Their
operands/arguments are called expressions. So we aren't discussing the
syntax.

2. In a language where you write add(2,3) what would you call 2 and 3 :
operands or arguments?

All that's special about operators is that they are often invoked using
a non-general format, and they tend to be built into the language.

John

E

#### Evertjan.

Dr J R Stockton wrote on 27 jan 2012 in comp.lang.javascript:
Observe :
A = new Array(5)
B = new Array(6)
for which A[<anything>] = B[<anything>] = undefined; yet String(B) is
visibly longer than String(A).

Only longer,
if you uphold the for javascript clearly wrong dogma,
that an array must be integer continuous from it's bottom to it's top
index.

I would say both arrays are just as short,
having no visible or invisible content.

arr.length just is a sort of missnomer for the read/write value of the
theoretical top index, also wrongly assuming the defined bottom index is
always 0.

T

#### Thomas 'PointedEars' Lahn

John said:
1. The syntax specification calls new a keyword and + a punctuator

No, the _lexical grammar_ of ECMAScript (Ed. 5.1) says that `new' is a
keyword (section 7.6.1.1), and that `+' is a punctuator (section 7.7).

The _syntactic grammar_ calls `new' and `+' operators, as in "11.2.2 The
`new' Operator" and "11.6.1 The Addition operator (+)".

"Productions of the lexical and RegExp grammars are distinguished by having
two colons â€œ::â€ as separating punctuation. [â€¦]" (section 5.1.2, last
paragraph).
Their operands/arguments are called expressions.

Correct for "operands", in the syntactic grammar. Operators do not have
arguments; functions (and by extension to OOP, methods) have them.
So we aren't discussing the syntax.

Yes, we are. `+' is an operator in the syntax of ECMAScript; it has
operands.
2. In a language where you write add(2,3) what would you call 2 and 3 :
operands or arguments?

I get it now: you are trolling again.
All that's special about operators is that they are often invoked using
a non-general format, and they tend to be built into the language.

Wrong.

PointedEars

J

#### John G Harris

No, the _lexical grammar_ of ECMAScript (Ed. 5.1) says that `new' is a
keyword (section 7.6.1.1), and that `+' is a punctuator (section 7.7).

So the terms 'keyword' and 'punctuator' are now available for use in
higher layers of the language's syntax specification.

E.g When saying that identifiers exclude keywords.

The _syntactic grammar_ calls `new' and `+' operators, as in "11.2.2 The
`new' Operator" and "11.6.1 The Addition operator (+)".

I'm sure you're going to find it quite difficult to prove that a section
title is normative. If you look closely you'll find that the text of
such sections doesn't say which symbols comprise the 'operator'.
E.g As in

"11.1.6 The Grouping Operator
The production PrimaryExpression : ( Expression ) is evaluated as follows:"
....

The word 'operator' is used informally in the standard.

"Productions of the lexical and RegExp grammars are distinguished by having
two colons â€œ::â€ as separating punctuation. [â€¦]" (section 5.1.2, last
paragraph).
Their operands/arguments are called expressions.

Correct for "operands", in the syntactic grammar. Operators do not have
arguments; functions (and by extension to OOP, methods) have them.

OOP, indeed.

In C++, the user-defined member function (aka method)

Thing operator+ (Thing t, int) { ... }

will cause

Thing a, b;
b = a + 1;

to compile and execute correctly.

FTR, this is not off-topic : it is entirely possible that one day one of
ECMAScript itself.

Yes, we are. `+' is an operator in the syntax of ECMAScript; it has
operands.

I get it now: you are trolling again.

See above.

Tell us what feature an operator has that is not listed there.

Or are you claiming all those university text books that define + as a
function are somehow wrong.

If at the beginning you'd said that "operand is the more usual name"
then there would have been no argument.

John

T

#### Thomas 'PointedEars' Lahn

John said:
So the terms 'keyword' and 'punctuator' are now available for use in
higher layers of the language's syntax specification.

Not "now". Those terms are far from new in the history of the ECMAScript
Language Specification. If only you would get yourself informed before you
posted â€¦
E.g When saying that identifiers exclude keywords.

That is self-evident. A programming language where identifiers could form a
non-empty intersecting set with keywords would not be overly useful. Only
recently (Ed. 5) ECMAScript has started allowing reserved words in the dot
property accessor notation, because in this evaluation context we *know*
that a keyword's meaning is not intended. It complicates parsing, though,
as there is an additional /IdentifierName/ production now.
I'm sure you're going to find it quite difficult to prove that a section
title is normative.

I do not have to prove that, for it is common knowledge that the section of
a technical specification is normative unless marked differently.
If you look closely you'll find that the text of
such sections doesn't say which symbols comprise the 'operator'.
E.g As in

"11.1.6 The Grouping Operator
The production PrimaryExpression : ( Expression ) is evaluated as
follows:"
...

The word 'operator' is used informally in the standard.

No, it is not. In this case, it is apparent that the /Expression/ is the
(single) operand to the Grouping Operator.
OOP, indeed.

In C++, the user-defined member function (aka method)

I am aware of operator overloading (e. g. in C++), but we are not discussing
those languages or possible implementations of ECMAScript written in those
languages. We are discussing the syntax of ECMAScript (implementations).
And again, in the syntax of ECMAScript, `+' is an operator; it has operands,
not arguments.

PointedEars

J

#### John G Harris

John G Harris wrote:

I am aware of operator overloading (e. g. in C++), but we are not discussing
those languages or possible implementations of ECMAScript written in those
languages. We are discussing the syntax of ECMAScript (implementations).
And again, in the syntax of ECMAScript, `+' is an operator; it has operands,
not arguments.

Attention! Thomas has forbidden the Mozilla team to contemplate adding
it destroys his case.

Wikipedia and an online dictionary agree with me : operators are just
functions it's convenient to distinguish from other functions.

<http://foldoc.org/operator>
<http://en.wikipedia.org/wiki/Operator_(programming)>

John