扩展AS3的数组访问运算符以"包装"超出范围的索引值

mat*_*amp 2 arrays flash actionscript actionscript-3

我真的希望能够使Flash的数组访问语法"包裹"在数组的边界上.

冗长的解释 -

var array:Array = ['a','b','c','d','e','f'];
Run Code Online (Sandbox Code Playgroud)

为简单起见,第一个索引为0,其值为第一个字母"a".要获得这个价值,我们会这样做 -

array[0]; // returns 'a'
Run Code Online (Sandbox Code Playgroud)

只要您用于访问数组的索引介于0和array.length之间(在我们的示例中为6),一切正常 - 但如果您使用这些边界之外的索引,则会关闭.

array[-3];
array[9]; // both return 'undefined'
Run Code Online (Sandbox Code Playgroud)

有时候这是一件好事 - 有时候你会发生这种情况,而且你很好.其他时候,你发现自己希望(或者至少我发现自己希望)它表现得更像这样 -

array[-3];
array[9]; // both return 'd'
Run Code Online (Sandbox Code Playgroud)

(例如,当您点击最后一张照片上的"下一个"时,照片库会跳回到开头)

我为此类事件反复使用了一小块代码,但是将索引传递给数组之前总是要改变它:

var index = -3;
while(index < 0){index += array.length}
array[index % array.length]; // returns 'd'
Run Code Online (Sandbox Code Playgroud)

...这很好,但我真正想做的是扩展Array对象本身,以便它自动"包装"超出范围的索引值.

TL; DR - 通过扩展Flash AS3的Array对象可以实现索引包装吗?

Jua*_*ano 8

查看Proxy类:http://livedocs.adobe.com/flex/2/langref/flash/utils/Proxy.html.

我自己没有用它,但它似乎可以完成这项工作.我修改了文档中的示例代码,它以您想要的方式工作.但是,我还没有对它进行彻底的测试,你可能想要这样做.就个人而言,我不会扩展数组,只是使用2种方法添加/检索一个简单的类,因为代理的想法对我来说似乎有点牵连.但那就是我.

package
{
    import flash.utils.Proxy;
    import flash.utils.flash_proxy;

    dynamic class ProxyArray extends Proxy {
        private var _item:Array;

        public function ProxyArray() {
            _item = new Array();
        }

        override flash_proxy function callProperty(methodName:*, ... args):* {
            var res:*;
            res = _item[methodName].apply(_item, args);
            return res;
        }

        override flash_proxy function getProperty(name:*):* {
            if(!isNaN(name)) {
                var index:int = name;
                while(index < 0) {
                    index += this.length;

                }
                return _item[index % this.length];
            }


            return _item[name];
        }

        override flash_proxy function setProperty(name:*, value:*):void {
            _item[name] = value;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

使用:

        var a:ProxyArray = new ProxyArray();
        // you can't use this syntax ['a','b','c'], since it would return an Array object
        a.push("a");
        a.push("b");
        a.push("c");
        a.push("d");
        a.push("e");
        a.push("f");

        trace(a[-3]);
        trace(a[9]); 
Run Code Online (Sandbox Code Playgroud)