unity js vs "real" js - arrays of objects

Whew… I apparently can’t get there from here?..

I’m trying to add some (shot) gems to an array, with the gem type, and its individual horizontal position as an individual object. ie:

{theGem:gem, horiz:hpos};

Once all the gems are shot and added to the array, I need to sort by the horizontal position (in order to see if the gems are in the correct order, left to right.)

In “real” JS, this would be easy:

 var deTray = new Array();

 function addToTheTray(gem, hpos){
              deTray[deTray.length] = {theGem:gem, horiz:hpos};
		}
		
		//unity error : Unknown identifiler "theGem"
		//unityerror : Unknown identifiler "horiz"

 function sortit(){
            deTray.sort(compareH);	
}	
// unity error:  The best overload for the method 'Array.sort()' is not compatible with the argument list '(callable(Object, Object) as int)'.

 function compareH(a,b){
	var aa = a.horiz;
	var bb = b.horiz;
	
	return ((aa < bb) ? -1 : ((aa > bb) ? 1 : 0));
	}
	
//unity	error: 'horiz' is not a member of 'Object'.

But I get a ton of errors, as above.

(I think the intent of the code is clear, but if not, I’ll be happy to explain further.)

Suggestions and/or sympathy greatly appreciated. TIA.

You would need to (in order of the errors):

  1. instead of {theGem:gem, horiz:hpos} you’d need to declare a class with “theGem” and “horiz” fields. You may also need to push the value onto the array instead of assigning it to the last entry:
class GemHolder
{
	var theGem:gem;
	var horiz:int; //I'm guessing this is an integer, change it if you need to
	
	function GemHolder(targetGem:gem, targetHoriz:int)
	{
		this.theGem = targetGem;
		this.horiz = targetHoriz;
	}
}

function addToTheTray(targetGem:gem, hpos:int)
{
	deTray.push(new GemHolder(targetGem, hpos));
}
  1. I think you need to strongly type your “compareH” method return value as:
    function compareH(a,b) : int

  2. strongly type your method parameters (and combined with #2 above)
    function compareH(a : gem, b : gem) : int

Thanks for the quick reply! :slight_smile:

I’ll give it a go, and report back.

I edited/added code to my post when you replied, re-read point #1.

Aha! Thanks again.

Back soon.

:smile:

Sorry for the delay: life intervened …

Almost got it, thanks to your help:

static var deTray = new Array();

}



class GemHolder 
{ 
   var theGem:String; 
   var horiz:float; //I'm guessing this is an integer, change it if you need to 
    
   function GemHolder(targetGem: String, targetHoriz:float) 
   { 
      this.theGem = targetGem; 
      this.horiz = targetHoriz; 
   } 
} 

static function addToTheTray(targetGem: String, hpos:float) 
{ 
   deTray.push(new GemHolder(targetGem, hpos)); 
}


static function sortit(){
deTray.Sort(compareH);	
//deTray.Sort();	
}	
	
static function compareH(a:GemHolder,b:GemHolder): int {
	var aa = a.horiz;
	var bb = b.horiz;
	
	return ((aa < bb) ? -1 : ((aa > bb) ? 1 : 0));
	}

All the code above seems just fine, as long as I comment out:

deTray.Sort(compareH);

It appears that Sort isn’t happy being overridden:

error: The best overload for the method ‘Array.Sort()’ is not compatible with the argument list ‘(callable(GemHolder, GemHolder) as int)’.

Sorry, looks like UnityScript’s Array.Sort method doesn’t support custom implementations. See: http://unity3d.com/support/documentation/ScriptReference/Array.Sort.html

You might need to implement your own. I may be wrong on this (perhaps there’s a different built-in way) since I avoid UnityScript like the plague.

Yep: that ref to the manual is what prompted my own “looks like it won’t work” reply… Nice to have it confirmed tho’.

I’ve ordered a book on C#… is that what you use?

and, again, my thanks for your time and courtesy.

Yup, I do all my Unity work in C# and use Visual Studio 2010 to do my programming in.

OK… thanks once again.

still testing… seems that I have to do

var gh = deTray*;*
gh.horiz etc
since detray*.horiz won’t compile.*
I’ll post finished code when/if I get it working! :slight_smile:

You don’t need to use C#, just something other than the JS Array class.

–Eric

Great! Suggestions? Some number of gems between 4 and 12, shot in random order, and sorted into proper order based on their X location, when shot.

Only thing I can come up with is “parallel” arrays: one for the gems, one for the X position.

Other ideas greatly welcomed!

I’d think that arrays of objects would be common (power ups of different types, with N remaining uses; weapons with N remaining bullets etc etc) How are such things normally handled?

(33 years of “real” programming (C, C++, assembley, etc) but Unity JS is totally new to me.)

edit:

I can do it by keeping three independent arrays:
gems;
hpos;
sorter;

As a gem is hit, I’ll record it in gems, and its hposition in hpos.

when I need to check the order, I’ll copy hpos to sorter; and sort sorter.

then iterate thru sorter, looking for the value in hpos, and use that index to access gems.

That would work. Not very elegant, but it would work…

You can use System.Array.Sort for that.

–Eric

I’ll check it out. Thanks, Eric!

Here, as promised is the conclusion to my problem: how to do the equivalent of sorting an array of objects in Unity Javascript. (Reading the thread will help this make sense.)

Bottomline: use three arrays; sort #3, and look up the result in #2, and use that index to find the “gem” in #1.

hth

static var theChar  = new Array();
static var thePosn  = new Array();
static var theSort  = new Array();

static function addToTheTray(targetGem: String, hpos:float) 
{ 
	
	var index = theChar.length;
	
	theChar[index] = targetGem;
	thePosn[index] = parseInt((hpos * 1000));
	theSort[index] = thePosn[index];
}

static function getUnsortedChar(hp:float){
		var leng = thePosn.length;

		for (var i = 0; i< leng; i++){
		if (thePosn[i] == hp) {
			var chara = theChar[i];
			break;
		}
		}
return chara;	
}

static function sortit(){

	theSort.Sort();	
	var mychar: String;
	var mystring : String;
	var leng = theSort.length;
	for (var i = 0; i< leng; i++){
			mystring += getUnsortedChar(theSort[i]);	
			} 
}