Wrench value from your Creo Investments Home Measure the benefits Simple Automation can bring Why
Automate?
A personal way to do PDM Peer to Peer
PDM
3D Drawings Model Based
Design
Smooth out unwanted sharp edges Other
Articles
www.proetoolbox.co.uk - Simple Automation made Simple

Creating a Unique Array

Many Pro/Web.Link applications involve processing long lists of information. E.g. you may want to create a list of all Parts in an Assembly. You can easily generate a long list of model names in the assembly and now want to filter it out.

<SCRIPT>
//The Source Array
var Src=new Array("A",
         "B","B","Z","P","Z","A");

//The Result Array
var Res = new Array();

//Process using a sort then parse
//method
Src.sort();
Res[0] = Src[0];
var z=Src.length
for (var i=1;i<z;i++)
{
  if (Src[i]!=Res[Res.length-1])
    Res[Res.length] = Src[i];
}
							
alert ("Before: "+Src.join('')+"\n"+
  "After: "+Res.join(''));
</SCRIPT>

The Conventional Method of Creating a Unique Array

In the example code (shown right) you can see that we first sort the Array, using Array.sort(), so that all similar items are together. Then we loop down the sorted Array, looking for pairs of values. At each pair we look for a match, if no match the entry is added to another Array.

The result is perfectly valid but in order to make it efficient it is essential to carry out a sort operation. Therefore the original order in which items existed is destroyed. I think this is an annoying feature and therefore looked for a different approach.

<SCRIPT>
//The Source Array

var Src=new Array("A",
         "B","B","Z","P","Z","A");

//Create a hash from Src
var z=Src.length;
var hash = new Array();
for (var i=0;i<z;i++)
{
	hash[Src[i]]=Src[i];
}

//The Result Array
var Res = new Array();
for (var i in hash) {
	Res[Res.length] = i;
}

var After = new Date();			
alert ("Before: "+Src.join('')+"\n"+
  "After: "+Res.join(''));
</SCRIPT>

Generating a Hash to Create a Unique Array

Instead of referencing an Array's elements with numbers (i.e. Src[1], Src[2] etc.), you can also create arrays with alphanumeric keys (i.e. Src['one'], Src['two']). Thus to generate a unique Array we simply have to loop around the Source Array and generate an Array where the keys are the elements from the Source. Other than an issue with Arrays defined in this manner NOT having access to the Array.length property the logic works great and is yet again testament to the power and flexibility of JavaScript.

The result is again perfectly valid AND (most importantly to me) is in the original order.

Wrap the Technique into a re-useable Function

<SCRIPT>
function MakeUnique(a)
{
  //Create a hash from 'a'
  var z=a.length;
  var hash = new Array();
  for (var i=0;i<z;i++)
  {
	hash[a[i]]=a[i];
  }

  //The Result Array
  var Out = new Array();
  for (var i in hash) {
	Out[Out.length] = i;
  }
  return Out;
}
</SCRIPT>

It may be tempting to add the Function as a member of the Array object (e.g. Array.prototype.makeUnique = function(){... ) BUT be very wary, adding to Array like this essentially adds properties to the Array object. New functions added into the prototype will appear in for/in loops, probably causing damage to an otherwise functional application.

<SCRIPT>
//The Source Array
var Src=new Array("A",
         "B","B","Z","P","Z","A");

Res = MakeUnique(Src);
			
alert ("Before: "+Src.join('')+"\n"+
  "After: "+Res.join(','));
</SCRIPT>

As soon as you have access to a function as shown far right, you can then use it in your code making it far more readable.

Conclusion

JavaScript Arrays can be used as Hashes. If you want to generate a unique list in the original order, this method is ideal.