forked from: Alphanum Algorithm
forked from Alphanum Algorithm (diff: 3)
AlphanumComparator.as (AS3 version) reference: http://www.davekoelle.com/alphanum.html http://www.breaktrycatch.com/alphanumeric-sorting-in-as3/
ActionScript3 source code
/**
* Copyright yonatan ( http://wonderfl.net/user/yonatan )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/eYkB
*/
// forked from civet's Alphanum Algorithm
/**
* AlphanumComparator.as (AS3 version)
*
* reference:
* http://www.davekoelle.com/alphanum.html
* http://www.breaktrycatch.com/alphanumeric-sorting-in-as3/
*/
package
{
import com.bit101.components.List;
import com.bit101.components.PushButton;
import com.bit101.components.Style;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.FileReference;
import flash.net.FileReferenceList;
public class Alphanum extends Sprite
{
private var _list:com.bit101.components.List;
private var _fileRefList:FileReferenceList;
private var _items:Array;
public function Alphanum()
{
Style.embedFonts = false;
Style.fontSize = 12;
Style.fontName = "Arial";
_list = new com.bit101.components.List(this, 10, 10);
_list.setSize(300, 300);
var buttonBrowse:PushButton = new PushButton(this, 10, 320, "OPEN", onBrowse);
var buttonSort:PushButton = new PushButton(this, 200, 320, "SORT", onSort);
}
private function onBrowse(event:Event):void
{
_fileRefList = new FileReferenceList();
_fileRefList.addEventListener(Event.SELECT, onSelect);
_fileRefList.browse();
}
private function onSelect(event:Event):void
{
var fileList:Array = _fileRefList.fileList;
var num:int = fileList.length;
var items:Array = [];
for(var i:int=i; i<num; i++) {
var fileRef:FileReference = fileList[i];
items[items.length] = {label:fileRef.name, data:fileRef};
}
_items = items;
_list.items = items;
}
private function onSort(event:Event):void
{
if(!_items || _items.length == 0) return;
var comparator:AlphanumComparator = new AlphanumComparator("label");
var itemsClone:Array = _items.slice();
itemsClone.sort(comparator.compareObject);
_list.items = itemsClone;
}
}
}
class AlphanumComparator
{
private var _fieldName:String;
public function AlphanumComparator(fieldName:String="name")
{
_fieldName = fieldName;
}
private function isDigit(char:String):Boolean
{
var code:int = char.charCodeAt(0);
return code >= 48 && code <= 57;
}
/** Length of string is passed in for improved efficiency (only need to calculate it once) **/
private function getChunk(s:String, length:int, marker:int):String
{
var chunk:String = "";
var c:String = s.charAt(marker);
chunk += c;
marker++;
if(isDigit(c)) {
while(marker < length) {
c = s.charAt(marker);
if(!isDigit(c)) break;
chunk += c;
marker++;
}
}
else {
while(marker < length) {
c = s.charAt(marker);
if(isDigit(c)) break;
chunk += c;
marker++;
}
}
return chunk;
}
public function compareObject(o1:Object, o2:Object):int
{
var s1:String = o1[_fieldName];
var s2:String = o2[_fieldName];
if(!s1 || !s2) return 0;
return compare(s1, s2);
}
public function compare(s1:String, s2:String):int
{
var marker1:int = 0;
var marker2:int = 0;
var length1:int = s1.length;
var lenght2:int = s2.length;
while(marker1 < length1 && marker2 < lenght2)
{
var chunk1:String = getChunk(s1, length1, marker1);
marker1 += chunk1.length;
var chunk2:String = getChunk(s2, lenght2, marker2);
marker2 += chunk2.length;
var result:int = 0;
// If both chunks contain numeric characters, sort them numerically
if(isDigit(chunk1.charAt(0)) && isDigit(chunk2.charAt(0))) {
// Simple chunk comparison by length.
var len:int = chunk1.length;
result = len - chunk2.length;
// If equal, the first different number counts
if(result == 0)
{
for(var i:int = 0; i < len; i++)
{
result = chunk1.charCodeAt(i) - chunk2.charCodeAt(i);
if(result != 0)
return normalize(result);
}
}
}
else {
//result = chunk1.compareTo(chunk2);
if(chunk1 < chunk2) {
result = -1;
}
else if(chunk1 > chunk2) {
result = 1;
}
else {
result = 0;
}
}
if(result != 0)
return normalize(result);
}
//comparison by length
return normalize(length1 - lenght2);
}
private function normalize(result:int):int
{
return result < 0 ? -1 : (result > 0 ? 1 : 0);
}
}