Javascript function to compare two objects?

Discussion in 'Programming' started by ibex333, Dec 30, 2012.

  1. ibex333

    ibex333 Diamond Member

    Joined:
    Mar 26, 2005
    Messages:
    3,430
    Likes Received:
    0
    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>
     
    #1 ibex333, Dec 30, 2012
    Last edited: Dec 30, 2012
  2. Cogman

    Cogman Lifer

    Joined:
    Sep 19, 2000
    Messages:
    10,086
    Likes Received:
    14
    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]);
     
  3. ibex333

    ibex333 Diamond Member

    Joined:
    Mar 26, 2005
    Messages:
    3,430
    Likes Received:
    0

    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)
    	
    
     
  4. PhatoseAlpha

    PhatoseAlpha Platinum Member

    Joined:
    Apr 10, 2005
    Messages:
    2,120
    Likes Received:
    0
    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.
     
    #4 PhatoseAlpha, Dec 30, 2012
    Last edited: Dec 30, 2012
  5. douglasb

    douglasb Diamond Member

    Joined:
    Apr 11, 2005
    Messages:
    3,163
    Likes Received:
    0
    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.
     
  6. ibex333

    ibex333 Diamond Member

    Joined:
    Mar 26, 2005
    Messages:
    3,430
    Likes Received:
    0
    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>
    
     
  7. douglasb

    douglasb Diamond Member

    Joined:
    Apr 11, 2005
    Messages:
    3,163
    Likes Received:
    0
    At the bottom,

    var same = compare(album0,album1);

    Should be:

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

    ibex333 Diamond Member

    Joined:
    Mar 26, 2005
    Messages:
    3,430
    Likes Received:
    0
    Still undefined...
     
  9. douglasb

    douglasb Diamond Member

    Joined:
    Apr 11, 2005
    Messages:
    3,163
    Likes Received:
    0
    Sorry, I read the code wrong. Your understanding of arrays in javascript is flawed. Read up on arrays.
     
  10. douglasb

    douglasb Diamond Member

    Joined:
    Apr 11, 2005
    Messages:
    3,163
    Likes Received:
    0
    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>
    
     
    #10 douglasb, Jan 5, 2013
    Last edited: Jan 5, 2013
  11. ibex333

    ibex333 Diamond Member

    Joined:
    Mar 26, 2005
    Messages:
    3,430
    Likes Received:
    0
    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?
     
    #11 ibex333, Jan 5, 2013
    Last edited: Jan 5, 2013
  12. douglasb

    douglasb Diamond Member

    Joined:
    Apr 11, 2005
    Messages:
    3,163
    Likes Received:
    0
    Because everything in Javascript is an object.
     
  13. ibex333

    ibex333 Diamond Member

    Joined:
    Mar 26, 2005
    Messages:
    3,430
    Likes Received:
    0
    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?
     
  14. douglasb

    douglasb Diamond Member

    Joined:
    Apr 11, 2005
    Messages:
    3,163
    Likes Received:
    0
    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.
     
Loading...