Javascript function to compare two objects?

ibex333

Diamond Member
Mar 26, 2005
4,090
119
106
Please take a look at my program. I cannot figure out what I am doing wrong. Code doesn't run.
I have two music albums that get populated with random info depending on user input. Then I have to compare if all the properties within two album objects are same.


Code:
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	</head>
	<body>
		<script type="text/javascript">
			/********* GLOBAL VARIABLES *********/
			var BR = "<br />";
			
			
			
			/********* FUNCTIONS *********/
			function compare(album[0]album[1])
			{
			
		 	var sameAlbums = false;
		 	
		 	//There has to be an easier way to do all this...
		 	if 
		 	(album[0].artistName === album[1].artistName &&
			album[0].albumTitle === album[1].albumTitle &&
			album[0].releaseYear === album[1].releaseYear && 
			album[0].ifHQ === album[1].ifHQ && 
			album[0].tracks[0] ===  album[1].tracks[0] &&
			album[0].tracks[1] ===  album[1].tracks[1] && 
			album[0].tracks[2] ===  album[1].tracks[2] && 
			album[0].tracks[3] ===  album[1].tracks[3] &&
			album[0].tracks[4] ===  album[1].tracks[4] && 
			album[0].tracks[5] ===  album[1].tracks[5] &&
			album[0].tracks[6] ===  album[1].tracks[6] &&
			album[0].tracks[7] ===  album[1].tracks[7] && 
			album[0].tracks[8] ===  album[1].tracks[8] &&
			album[0].tracks[9] ===  album[1].tracks[9] &&
			album[0].tracks[10] ===  album[1].tracks[10]
			)
			
			{
				sameAlbums = true;
			}
		return sameAlbums;
			}
			
			
			
			/*function compareObject(album[0], album[1])
	{
		for (var key in album[0])
		{
			if (album[0].artistName !== album[1].artistName)
			{
				return false;
			}
		}
		for (var key in album[1])
		{
			if (album[1].artistName !== album[0].artistName)
			{
				return false;
			}
		}
		return true;
	}
	*/

			/********* MAIN *********/
			function main() 
			{

				var alb = new album(2);
				

				for (var i = 0; i < album.length; i++) 
				{
					album[i] = 
					{
						artistName: "",
						albumTitle: "",
						releaseYear: 0,
						ifHQ: "",
						tracks: undefined //tracks here
					};
					album[i].artistName = prompt("What is the artist's name?");
					album[i].albumTitle = prompt("What is the album title?");
					album[i].releaseYear = parseFloat(prompt("What is the album's release year"));
					album[i].ifHQ = prompt("Is the album high quality? Y/N");
					
						while (!(album[i].ifHQ === "Y" || album[i].ifHQ === "N" || album[i].ifHQ === "YES" || album[i].ifHQ === "NO"))
					{		
						album[i].ifHQ = prompt("You have entered an invalid response. Is " + album[i].title + " a ifHQ album, Y/N?");
						album[i].ifHQ = album[i].ifHQ.toUpperCase();
					}	 
					
					if (album[i].ifHQ === "Y")
					{
						album[i].ifHQ = true;
					}
					else
					{
						album[i].ifHQ = false;
					}
					album[i].tracks = new albumay(10);
					
					for (var j = 0 + 1; j < album[i].tracks.length; j++) 
					{
						album[i].tracks[j] = prompt("Enter track" + (j + 1));


					}
				}
			for (var key in album[0])
			{
			document.write(key + ": " + album[0][key] + " " );
			document.write(BR);
			}
			for (var key in album[1])
			{
			document.write(key + ": " + album[1][key] + " " );
			document.write(BR);
			}
			
			}
			
			compare(album[0],album[1]);

			// This line calls main, don't change it:
			main();
		</script>
	</body>

</html>
 
Last edited:

Cogman

Lifer
Sep 19, 2000
10,277
125
106
There is no typing in javascript (sort of...) So when you say

Code:
function compare(a[0], b[1])

The javascript interpreter has no idea what you are trying to say.

To make things work, You would do something like this.

Code:
function compare(a, b)
{
   dostuff();
}

and you would call the function like this

Code:
var isTheSame = compare(album[0], album[1]);
 

ibex333

Diamond Member
Mar 26, 2005
4,090
119
106
There is no typing in javascript (sort of...) So when you say

Code:
function compare(a[0], b[1])

The javascript interpreter has no idea what you are trying to say.

To make things work, You would do something like this.

Code:
function compare(a, b)
{
   dostuff();
}

and you would call the function like this

Code:
var isTheSame = compare(album[0], album[1]);


I am not sure I understand what you are saying. I cant compare a and b and not a[0],b[1] because my albums have numbers, so I have to included those.

I keep getting this error in firebug:

Code:
SyntaxError: missing ) after formal parameters
[Break On This Error] 	

function compare(album[0], album[1])

Assign...V3.html (line 14, col 25)
 

PhatoseAlpha

Platinum Member
Apr 10, 2005
2,131
21
81
You've defined your function incorrectly. [ ] are used as array indexers, which make no sense in a function definition.

Try this:
Code:
			/*function compareObject(album0, album1)
	{
		for (var key in album0)
		{
			if (album0.artistName !== album1.artistName)
			{
				return false;
			}
		}
		for (var key in album1)
		{
			if (album1.artistName !== album0.artistName)
			{
				return false;
			}
		}
		return true;
	}

The array index is used when actually calling that function. But you don't use the array index in the function definition like that - it's invalid syntax because the function doesn't care about what the index of it is in array it doesn't even know about.
 
Last edited:

douglasb

Diamond Member
Apr 11, 2005
3,163
0
76
He is saying that the signature for your compare method is wrong. We (humans) can tell by looking at it that album[0] and album[1] are elements of an array but Javascript has no idea what you are saying (and if it did, it wouldn't care, because everything in Javascript is an object).

Therefore, your compare method needs to be fixed to take in either 1 object (the entire array) or 2 objects (the 2 elements you are comparing). You could take in the whole array and compare the elements at index 0 and 1, or better yet, you could have it take in 2 objects, which is more generic and useful if you wish to expand your program later.

So you would declare it like:
Code:
function compare(album0, album1)
{
			
 	//There IS an easier way to do all this...
 	return 
	 	(
                         album0.artistName === album1.artistName &&
 			 album0.albumTitle === album1.albumTitle &&
 			 album0.releaseYear === album1.releaseYear && 
		 	 album0.ifHQ === album1.ifHQ && 
			 album0.tracks ===  album1].tracks
		);
}

and you would use it like:

Code:
var foo = compare (firstAlbum, secondAlbum);
OR
Code:
var foo = compare (album[0], album[1]);

Honestly, if you are just trying to determine if the two objects refer to the same area in memory, you could just do:
Code:
var foo = (album[0] === album[1]);
but this will return false for different instantiations of the same type of object.
 

ibex333

Diamond Member
Mar 26, 2005
4,090
119
106
firebug says album0 and album1 are not defined. But how are they not defined when I created them using an array?


Code:
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	</head>
	<body>
		<script type="text/javascript">
			/********* GLOBAL VARIABLES *********/
			var BR = "<br />";
			var ES = " ";
			
			
			
			/********* FUNCTIONS *********/
		
		
		function compare(album0, album1)
{
			
 	//This seems to do exactly what's needed...
 	return 
	 	(
             album0.artistName === album1.artistName &&
 			 album0.albumTitle === album1.albumTitle &&
 			 album0.releaseYear === album1.releaseYear && 
		 	 album0.ifHQ === album1.ifHQ && 
			 album0.tracks ===  album1.tracks
		);
}
	

			/********* MAIN *********/
			function main() 
			{

				var alb = new album(2);
				

				for (var i = 0; i < album.length; i++) 
				{
					album[i] = 
					{
						artistName: "",
						albumTitle: "",
						releaseYear: 0,
						ifHQ: "",
						tracks: undefined //tracks here
					};
					album[i].artistName = prompt("What is the artist's name?");
					album[i].albumTitle = prompt("What is the album title?");
					album[i].releaseYear = parseFloat(prompt("What is the album's release year"));
					album[i].ifHQ = prompt("Is the album high quality? Y/N");
					
						while (!(album[i].ifHQ === "Y" || album[i].ifHQ === "N" || album[i].ifHQ === "YES" || album[i].ifHQ === "NO"))
					{		
						album[i].ifHQ = prompt("You have entered an invalid response. Is " + album[i].title + " a ifHQ album, Y/N?");
						album[i].ifHQ = album[i].ifHQ.toUpperCase();
					}	 
					
					if (album[i].ifHQ === "Y")
					{
						album[i].ifHQ = true;
					}
					else
					{
						album[i].ifHQ = false;
					}
					album[i].tracks = new trackList(10);
					
					for (var j = 0 + 1; j < album[i].tracks.length; j++) 
					{
						album[i].tracks[j] = prompt("Enter track" + (j + 1));


					}
				}
			for (var key in album[0])
			{
			document.write(key + ": " + album[0][key] + " " );
			document.write(BR);
			}
			for (var key in album[1])
			{
			document.write(key + ": " + album[1][key] + " " );
			document.write(BR);
			}
			
			}
			
			var same = compare(album0,album1);
			document.write(same);

			// This line calls main, don't change it:
			main();
		</script>
	</body>

</html>
 

douglasb

Diamond Member
Apr 11, 2005
3,163
0
76
At the bottom,

var same = compare(album0,album1);

Should be:

var same = compare(album[0],album[1]);
 

douglasb

Diamond Member
Apr 11, 2005
3,163
0
76
Sorry, I read the code wrong. Your understanding of arrays in javascript is flawed. Read up on arrays.
 

douglasb

Diamond Member
Apr 11, 2005
3,163
0
76
This is more like what you are looking for:

Code:
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	</head>
	<body>
		<script type="text/javascript">
			/********* GLOBAL VARIABLES *********/
			var BR = "<br />";
			var ES = " ";
			
			
			
			/********* FUNCTIONS *********/
		
		
			function compare(album0, album1)
			{
			
				//This seems to do exactly what's needed...
				var sameTracks = true;
				for(var i=0; i < album0.length; i++)
				{
					if(! (album0.tracks[i] === album1.tracks[i]))
						sameTracks=false;
				}
				for(var i=0; i < album1.length; i++)
				{
					if(! (album0.tracks[i] === album1.tracks[i]))
						sameTracks=false;
				}
				
				if 
				(
					album0.artistName === album1.artistName &&
					album0.albumTitle === album1.albumTitle &&
					album0.releaseYear === album1.releaseYear && 
					album0.ifHQ === album1.ifHQ && 			
					album0.tracks.length ===  album1.tracks.length &&
					sameTracks === true
				)
				{
					return true
				}
				else
				{
					return false
				};
			}
	

			/********* MAIN *********/
			function main() 
			{

				
				for (var i = 0; i < album.length; i++) 
				{
					album[i] = 
					{
						artistName: "",
						albumTitle: "",
						releaseYear: 0,
						ifHQ: "",
						tracks: undefined //tracks here
					};

					album[i].artistName = prompt("What is the artist's name?");
					album[i].albumTitle = prompt("What is the album title?");
					album[i].releaseYear = parseFloat(prompt("What is the album's release year"));
					album[i].ifHQ = prompt("Is the album high quality? Y/N");
					
					while (!(album[i].ifHQ === "Y" || album[i].ifHQ === "N" || album[i].ifHQ === "YES" || album[i].ifHQ === "NO"))
					{		
						album[i].ifHQ = prompt("You have entered an invalid response. Is " + album[i].title + " a ifHQ album, Y/N?");
						album[i].ifHQ = album[i].ifHQ.toUpperCase();
					}	 
					
					if (album[i].ifHQ === "Y")
					{
						album[i].ifHQ = true;
					}
					else
					{
						album[i].ifHQ = false;
					}
					
					album[i].tracks = new Array(2);
					
					for (var j = 0; j < album[i].tracks.length; j++) 
					{
						album[i].tracks[j] = prompt("Enter track " + (j + 1));
					}
				}
				
				for (var key in album[0])
				{
					document.write(key + ": " + album[0][key] + " " );
					document.write(BR);
				}
				for (var key in album[1])
				{
					document.write(key + ": " + album[1][key] + " " );
					document.write(BR);
				}
			

			}

			var album = new Array(2)
			// This line calls main, don't change it:
			main();
			var same = compare(album[0],album[1]);
			alert(same);
			
		</script>
	</body>

</html>
 
Last edited:

ibex333

Diamond Member
Mar 26, 2005
4,090
119
106
thanks for fixing.. I am looking through this to see what I messed up...

Code:
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	</head>
	<body>
		<script type="text/javascript">
			/********* GLOBAL VARIABLES *********/
			var BR = "<br />";
			var ES = " ";

			//very tough assigment. Definitely wasnt even remotely ready for it when it was given. Required good understanding of arrays and for..in loops which I never really developed due to having to transfer attention to newer topics all the time

			/********* FUNCTIONS *********/


			function compare(album0, album1) {

				//This seems to do exactly what's needed... but sadly I dont have time to test every possible scenario.
				var sameTracks = true;
				for (var i = 0; i < album0.length; i++) {
					if (!(album0.tracks[i] === album1.tracks[i])) sameTracks = false;
				}
				for (var i = 0; i < album1.length; i++) {
					if (!(album0.tracks[i] === album1.tracks[i])) sameTracks = false;
				}

				if (
				album0.artistName === album1.artistName && album0.albumTitle === album1.albumTitle && album0.releaseYear === album1.releaseYear && album0.ifHQ === album1.ifHQ && album0.tracks.length === album1.tracks.length && sameTracks === true) {
					return true
				}
				else {
					return false
				};
			}


			[b]function copy(album1) //the copy function
			{


				//properties will be copied over from original album1 into copy
				var albumCopy = 
				{
					artistName: "",
					albumTitle: "",
					releaseYear: 0,
					ifHQ: "",
					tracks: undefined
				};
				//copies original object values item for item into duplicate album
				for (var key in album1) 
				
				{
				albumCopy[key] = album1[key];
				}
				return albumCopy;
			}
[/b]

			/********* MAIN *********/
			function main() {

				var album = new Array(2)






				for (var i = 0; i < album.length; i++) //ok, so basically this loop is responsible for creating the album objects...
				{
					album[i] = {
						artistName: "",
						albumTitle: "",
						releaseYear: 0,
						ifHQ: "",
						tracks: undefined //tracks here
					};

					album[i].artistName = prompt("What is the artist's name?");
					album[i].albumTitle = prompt("What is the album title?");
					album[i].releaseYear = parseFloat(prompt("What is the album's release year"));
					album[i].ifHQ = prompt("Is the album high quality? Y/N");

					while (!(album[i].ifHQ === "Y" || album[i].ifHQ === "N" || album[i].ifHQ === "YES" || album[i].ifHQ === "NO")) //to handle bad input
					{
						album[i].ifHQ = prompt("You have entered an invalid response. Is " + album[i].title + " a ifHQ album, Y/N?");
						album[i].ifHQ = album[i].ifHQ.toUpperCase();
					}

					if (album[i].ifHQ === "Y") {
						album[i].ifHQ = true;
					}
					else {
						album[i].ifHQ = false;
					}

					album[i].tracks = new Array(2); // the tracks property of each album object is an array of tracks... 

					for (var j = 0; j < album[i].tracks.length; j++) {
						album[i].tracks[j] = prompt("Enter track " + (j + 1));
					}
				}

				for (var key in album[0]) //and these for... in loops navigate through properties for these objects to output what was stored in them
				{
					document.write(key + ": " + album[0][key] + " ");
					document.write(BR);
				}
				for (var key in album[1]) {
					document.write(key + ": " + album[1][key] + " ");
					document.write(BR);
				}

				var same = compare(album[0], album[1]);
				document.write("The status of both albums being identical is" + ES + same + BR);
				var copiedAlbum = copy(album[1]);
				document.write(copiedAlbum);
			}



			// This line calls main, don't change it:
			main();






			
		</script>
	</body>

</html>

I created a copy function to create a copy of album1, but what I get as an output is [object Object]

Why is this?
 
Last edited:

ibex333

Diamond Member
Mar 26, 2005
4,090
119
106
How can I avoid this error? I read up on it, and It has something to do with toString property. According to stack overflow, I have to create my own toString method but I don't understand this stuff at all.

Is there a simple way to create a function that copies an object along with all of its properties and displays it?
 

douglasb

Diamond Member
Apr 11, 2005
3,163
0
76
How can I avoid this error? I read up on it, and It has something to do with toString property. According to stack overflow, I have to create my own toString method but I don't understand this stuff at all.

Is there a simple way to create a function that copies an object along with all of its properties and displays it?

Yes, and it's really simple. You are already showing all of the objects properties right before you compare the 2 objects. Look at your code again. The answer is already there. Just put it in a function.