Short filenames based on weighted curve
Here is a small function that will shorten a filename based on a weighted curve.
I used a simple sine curve given the start and end of the filename the highest weights.
Actionscript:
-
/**
-
* This function will return a shorter representation of the path.
-
* Each token in the path is given a certain weight based on it's position in the filename.
-
* Tokens with lower weight are removed first to achieve the desired length.
-
* Tokens at the start and end of the filename have higher weights, the last token has the heighest weight.
-
* @param filename The filename to operate on
-
* @param maxChars The maximum length of the returned filename.
-
* The length of the slash character is taken into account.
-
* Note: The function will always return a string that is at least 3 chars in length. This would be "..."
-
* @param allowPartials Allow tokens be partially visible instead of stripping them completely to fit the desired size
-
* @return The shortened filename
-
*/
-
public static function shorten( filename:String, maxChars:uint, allowPartials:Boolean = false ):String {
-
if( filename.length <= maxChars ) return filename;
-
-
var tokens:Array = filename.split( SLASH );
-
var weightedTokens:Array = new Array( tokens.length );
-
-
for( var i:uint = 0; i <weightedTokens.length; ++i ) {
-
var weight:Number = Math.abs( Math.sin( i / ( weightedTokens.length - 1 ) * Math.PI - Math.PI * 0.5 ) );
-
weightedTokens[ i ] = { token: tokens[ i ], weight: weight, position: i };
-
}
-
weightedTokens[ weightedTokens.length - 1 ].weight += 1; // Last token has the highest weight possible
-
-
weightedTokens.sortOn( "weight", Array.NUMERIC | Array.DESCENDING );
-
-
var currentLength:uint = 0;
-
var lastToken:uint = 0;
-
for( lastToken = 0; lastToken <weightedTokens.length; ++lastToken ) {
-
var currentTokenLength:uint = String( weightedTokens[ lastToken ].token ).length;
-
-
if( currentLength + currentTokenLength + 3 + ( lastToken * SLASH.length )>= maxChars ) {
-
if( allowPartials ) {
-
var diff:int = maxChars - ( currentLength + currentTokenLength + 3 + ( lastToken * SLASH.length ) );
-
var finalDiff:int = diff - ( 3 + SLASH.length );
-
if( currentTokenLength + finalDiff> 0 ) {
-
weightedTokens[ lastToken ].token = String( weightedTokens[ lastToken ].token ).substr( 0, currentTokenLength + finalDiff ) + "...";
-
++lastToken;
-
}
-
}
-
break;
-
}
-
-
currentLength += currentTokenLength;
-
}
-
-
if( currentLength == 0 ) {
-
return "...";
-
}
-
-
if( lastToken <weightedTokens.length ) {
-
weightedTokens.splice( lastToken, weightedTokens.length - lastToken, { token: "...", weight: 0, position: weightedTokens[ lastToken ].position } );
-
}
-
weightedTokens.sortOn( "position", Array.NUMERIC );
-
-
var shortFilename:String = "";
-
for( var tokenIdx:uint = 0; tokenIdx <weightedTokens.length; ++tokenIdx ) {
-
if( tokenIdx> 0 ) shortFilename += SLASH;
-
shortFilename += String( weightedTokens[ tokenIdx ].token );
-
}
-
-
return shortFilename;
-
}

February 12th, 2008 at 22:42
Of course, SLASH has to be defined for this to work. And example would be:
public static const SLASH:String = “\\”;
October 31st, 2008 at 05:23
hi…
thanks…