Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Переменные в строке (http://www.flasher.ru/forum/showthread.php?t=208835)

inozemcev 05.09.2014 21:36

Переменные в строке
 
В питоне есть очень удобная конструкция замены специальных символов на значения:

Код AS3:

return " Takes %d units of health " % (3) // вернет "Takes 3 units of health"

Помогите написать функцию, которая могла бы принимать три аргумента и возвращать обработанную строку.

Код AS3:

parse (str:String, symbol:String, arr:Array) :String


Gerbert 05.09.2014 21:46

Вы издеваетесь чтоль? У Вас две темы в блоге и Вы не знает, как сделать метод склеивания строк?
Кто Вам тогда темы для блога писал? Или Вы считаете нормальным вести блог, когда не знаете, как сделать простое склеивание?

nubideus 05.09.2014 22:38

"123 %d 321".replace("%d", "asddsa")
// "123 asddsa 321"
profit

GBee 06.09.2014 00:06

Gerbert, что вы такой агрессивный? Может человек никогда со строками не работал и спрашивает, как лучше. К тому же задача не так проста, как кажется.

nubideus
"Привет %s, тебе сегодня исполнилось %d %s. Сегодня в %s день могут смотреть не %s"
["Юзернейм", "4", "года", "завтрашний", "только лишь все"]

Добавлено через 4 минуты
Я бы сделал как во флексе ResourceManager там замена напрямую из массива по индексу:
"Привет {0}, тебе сегодня исполнилось {1} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!"
["Юзернейм", "4", "года", "завтрашний", "только лишь все"]

И гибче получается

Gerbert 06.09.2014 00:30

Цитата:

Gerbert, что вы такой агрессивный? Может человек никогда со строками не работал и спрашивает, как лучше. К тому же задача не так проста, как кажется.
Вы можете поверить в то, что человек-программист со стажем минимум четыре года никогда не работал со строками?

Ну а вообще, да, я извиняюсь перед ТС - простите! Это не мое дело.

GBee 06.09.2014 00:46

Цитата:

Вы можете поверить в то, что человек-программист со стажем минимум четыре года никогда не работал со строками?
Вот вы провокатор :о) Да, странно, конечно. Может лень напала?

dimarik 06.09.2014 01:13

Ну угнали у него аккаунт, спрашивают чего непонятно, чего панику разводить?

nubideus 06.09.2014 01:25

Код AS3:

var arr:Array = ["asd", 1, 2, 4];
trace("{1}, {2}, {3}, {0}, {0}".replace(/{[0-9]+}+/g, function(substr:String, i:uint, str:String):String {
        return arr[uint(substr.slice(1, -1))];
})); // 1, 2, 4, asd, asd

Код AS3:

var arr:Array = ["Юзернейм", "4", "года", "завтрашний", "только лишь все"];
var str:String = "Привет %s, тебе сегодня исполнилось %d %s. Сегодня в %s день могут смотреть не %s";
trace(str.replace(/%s|%d/g, function(substr:String, i:uint, str:String):String {
        switch(substr) {
                case "%s": return arr.shift();
                case "%d": return arr.shift();
        }
}));
// Привет Юзернейм, тебе сегодня исполнилось 4 года. Сегодня в завтрашний день могут смотреть не только лишь все

profit

inozemcev 06.09.2014 01:44

Принимаю ваш праведный гнев. Просто не хотел отвлекаться от основных тасков и подвесил функцию на сообщество. Иcходил из того, что функция будет полезна многим, поэтому и спросил.

p.s Пишу свой Heartstone с блекджеком и шлюхами. Код есть на гитхабе.

GBee 06.09.2014 02:49

Цитата:

profit
Клёво!

MikroAcse 06.09.2014 14:08

Медленный, но менее морочный вариант :D
Код AS3:

var arr:Array = ["Юзернейм", "4", "года", "завтрашний", "только лишь все"];
var str:String = "Привет {0}, тебе сегодня исполнилось {1} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!";
 
var len:int = arr.length;
for(var i:int = 0; i < len; i++) {
        str = str.split("{" + i + "}").join(arr[i]);
}
 
trace(str);

1000000 выполнений ~ 10 секунд (вариант SlavaRa ~ 4 секунды)

СлаваRa 06.09.2014 17:44

Небольшой тестик по теме
Код AS3:

package {
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.text.TextField;
        import flash.utils.getTimer;
        import flash.utils.setTimeout;
 
        /**
        * @author SlavaRa
        */

        public class Main extends Sprite {
 
                public static const COUNT:int = 1000000;
 
                public function Main() {
                        super();
                        _field = new TextField();
                        _field.width = 800;
                        _field.height = 600;
                        addChild(_field);
                        setTimeout(runTests, 1000);
                }
 
                private function runTests():void {
                        //var str:String;
                        //var arr:Array;
                        //arr = ["Юзернейм", "4", "года", "завтрашний", "только лишь все"];
                        //str = "Привет %s, тебе сегодня исполнилось %d %s. Сегодня в %s день могут смотреть не %s.";
                        //trace(str.replace(/%s|%d/g, function(substr:String, i:uint, str:String):String {
                                //switch(substr) {
                                        //case "%s": return arr.shift();
                                        //case "%d": return arr.shift();
                                //}
                        //}));//Привет Юзернейм, тебе сегодня исполнилось 4 года. Сегодня в завтрашний день могут смотреть не только лишь все.
                        //arr = ["Юзернейм", "4", "года", "завтрашний", "только лишь все"];
                        //str = "Привет {0}, тебе сегодня исполнилось {1} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!";
                        //var len:int = arr.length;
                        //for(var i:int = 0; i < len; i++) {
                                //str = str.split("{" + i + "}").join(arr[i]);
                        //}
                        //trace(str);
                        //Привет Юзернейм, тебе сегодня исполнилось 4 года. Сегодня в завтрашний день могут смотреть не только лишь все. Не скучай, Юзернейм!
                        //var args:Vector.<String> = new <String>["Юзернейм", "4", "года", "завтрашний", "только лишь все"];
                        //str = "Привет {0}, тебе сегодня исполнилось {1} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!";
                        //var length:int = args.length;
                        //for(var i:int = 0; i < length; i++) {
                                //var pattern:String = "{" + i + "}";
                                //while(str.indexOf(pattern) != -1) {
                                        //str = str.replace(pattern, args[i]);
                                //}
                        //}
                        //trace(str);
                        //Привет Юзернейм, тебе сегодня исполнилось 4 года. Сегодня в завтрашний день могут смотреть не только лишь все. Не скучай, Юзернейм!
                        testNubideus();//testNubideus:13652
                        testMikroAcse();//testMikroAcse:9039
                        testSlavaRa();//testSlavaRa:3495
                }
 
                private var _field:TextField;
 
                private function testNubideus():void {
                        var arr:Array = ["Юзернейм", "4", "года", "завтрашний", "только лишь все"];
                        var str:String = "Привет %s, тебе сегодня исполнилось %d %s. Сегодня в %s день могут смотреть не %s. Не скучай, {0}!";
                        var stamp:int = getTimer();
                        for (var j:int = 0; j < COUNT; j++) {
                                str.replace(/%s|%d/g, function(substr:String, i:uint, str:String):String {
                                        switch(substr) {
                                                case "%s": return arr.shift();
                                                case "%d": return arr.shift();
                                        }
                                });
                        }
                        _field.appendText("\ntestNubideus:" + (getTimer() - stamp));
                }
 
                private function testMikroAcse():void {
                        var arr:Array = ["Юзернейм", "4", "года", "завтрашний", "только лишь все"];
                        var str:String = "Привет {0}, тебе сегодня исполнилось {1} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!";
                        var stamp:int = getTimer();
                        for (var j:int = 0; j < COUNT; j++) {
                                var len:int = arr.length;
                                for(var i:int = 0; i < len; i++) {
                                        str = str.split("{" + i + "}").join(arr[i]);
                                }
                        }
                        _field.appendText("\ntestMikroAcse:" + (getTimer() - stamp));
                }
 
                private function testSlavaRa():void {
                        var args:Vector.<String> = new <String>["Юзернейм", "4", "года", "завтрашний", "только лишь все"];
                        var str:String = "Привет {0}, тебе сегодня исполнилось {1} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!";
                        var stamp:int = getTimer();
                        for (var j:int = 0; j < COUNT; j++) {
                                var length:int = args.length;
                                for(var i:int = 0; i < length; i++) {
                                        var pattern:String = "{" + i + "}";
                                        while(str.indexOf(pattern) != -1) {
                                                str = str.replace(pattern, args[i]);
                                        }
                                }
                        }
                        _field.appendText("\ntestSlavaRa:" + (getTimer() - stamp));
                }
        }
}

из теста видно, код от Nubideus выполняется с ошибкой(по-моему где-то я такое видел)

UPD1:
самый быстрый Inline вариант, стабильно 4 сек. на миллион
Код AS3:

[Inline]
public static function format(source:String, args:Vector.<String>):String {
        for(var i:int = args.length; --i >= 0; ) {
                var pattern:String = "{" + i + "}";
                label: if(source.indexOf(pattern) != -1) {
                        source = source.replace(pattern, args[i])
                        goto label;
                }
        }
        return source;
}


Nooob 06.09.2014 22:23

Код AS3:

class StringUtils
{
        private static const regExp:RegExp = /{(\w)}/g;
        private static var repl:Array;
 
        public static function format (source:String, ... args):String
        {
                repl = args;
                return source.replace(regExp, replaceFunc);
        }
 
        private static function replaceFunc (substr:String, group:int, i:uint, str:String):String
        {
                return repl[group];
        }
}
var result:String = StringUtils.format("Привет {0}, тебе сегодня исполнилось {1} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!", "Юзернейм", "4", "года", "завтрашний", "только лишь все");

так симпатичнее

testSlavaRa:8746
testNooob:8163

СлаваRa 06.09.2014 22:43

тест вашего и моего кода, в release(миллион итераций)
testSlavaRa:4100
testNooob:20680

все 4 теста с вашим кодом падают по таймауту

UPD1: + ваш спокойно себе заменит и {a}, {b}, {c}, ... чего делать не должен(

nubideus 06.09.2014 22:54

Цитата:

код от Nubideus выполняется с ошибкой
ошибка то где?
>Сегодня в %s день могут смотреть не %s. Не скучай, {0}!
>Сегодня в завтрашний день могут смотреть не только лишь все. Не скучай, {0}!
тут ошибка в том, что ты не тот код скопировал.
ну и в регекспе лишний плюсик /{[0-9]+}+/g, но и с ним работает, так что не стал править

вы не сможете отладить, если в строке будет {n}, где n больше или равно arg.length, по идее должно выдавать range error. я этого не учел потому что пофиг ваще
например "asd asd {9999} sad"

СлаваRa 06.09.2014 22:56

Извиняюсь, да.. мой косяк, исправил сообщение.

Nooob 06.09.2014 22:58

ну ещёб, у тебя там ошибки в коде, в следующей итерации str будет уже старый и поэтому будет работать быстрее.
если уж инлайнить то
Код AS3:

package
{
        import flash.display.Sprite;
        import flash.text.TextField;
        import flash.utils.getTimer;
        import flash.utils.setTimeout;
 
        /**
        * @author SlavaRa
        */

        public class Main extends Sprite
        {
                public static const COUNT:int = 1000000;
 
                public function Main ()
                {
                        super();
                        _field = new TextField();
                        _field.width = 800;
                        _field.height = 600;
                        addChild(_field);
                        setTimeout(runTests, 1000);
                }
 
                private function runTests ():void
                {
                        testNubideus(); //testNubideus:7695
                        testMikroAcse(); //testMikroAcse:10034
                        testSlavaRa(); //testSlavaRa:7824
                        testNooob(); //testNooob:7493
                }
 
                private var _field:TextField;
 
                private function testNubideus ():void
                {
                        var str:String    = "Привет %s, тебе сегодня исполнилось %d %s. Сегодня в %s день могут смотреть не %s. Не скучай, {0}!";
                        var func:Function = function (substr:String, i:uint, str:String):String {
                                switch (substr) {
                                        case "%s": {return arr.shift();}
                                        case "%d": {return arr.shift();}
                                }
                        };
                        var regexp:RegExp = /%s|%d/g;
                        var stamp:int    = getTimer();
                        for (var j:int = 0; j < COUNT; j++)
                        {
                                var arr:Array    = ["Юзернейм", "4", "года", "завтрашний", "только лишь все"];
                                var result:String = str.replace(regexp, func);
                        }
                        _field.appendText("\ntestNubideus:" + (getTimer() - stamp));
                }
 
                private function testMikroAcse ():void
                {
                        var arr:Array  = ["Юзернейм", "4", "года", "завтрашний", "только лишь все"];
                        var str:String = "Привет {0}, тебе сегодня исполнилось {1} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!";
                        var stamp:int  = getTimer();
                        for (var j:int = 0; j < COUNT; j++)
                        {
                                var result:String = str;
                                var len:int      = arr.length;
                                for (var i:int = 0; i < len; i++)
                                {
                                        result = result.split("{" + i + "}").join(arr[i]);
                                }
                        }
                        _field.appendText("\ntestMikroAcse:" + (getTimer() - stamp));
                }
 
                private function testSlavaRa ():void
                {
                        var args:Vector.<String> = new <String>["Юзернейм", "4", "года", "завтрашний", "только лишь все"];
                        var str:String          = "Привет {0}, тебе сегодня исполнилось {1} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!";
                        var stamp:int            = getTimer();
                        for (var j:int = 0; j < COUNT; j++)
                        {
                                var result:String = str;
                                var length:int    = args.length;
                                for (var i:int = 0; i < length; i++)
                                {
                                        var pattern:String = "{" + i + "}";
                                        while (result.indexOf(pattern) != -1)
                                        {
                                                result = result.replace(pattern, args[i]);
                                        }
                                }
                        }
                        _field.appendText("\ntestSlavaRa:" + (getTimer() - stamp));
                }
 
                private function testNooob ():void
                {
                        var args:Vector.<String> = new <String>["Юзернейм", "4", "года", "завтрашний", "только лишь все"];
                        var str:String          = "Привет {0}, тебе сегодня исполнилось {1} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!";
                        var regExp:RegExp        = /{(\w)}/g;
                        var replaceFunc:Function = function (substr:String, group:int, i:uint, str:String):String
                        {
                                return args[group];
                        }
 
                        var stamp:int            = getTimer();
                        for (var j:int = 0; j < COUNT; j++)
                        {
                                var result:String = str.replace(regExp, replaceFunc);
                        }
                        _field.appendText("\ntestNooob:" + (getTimer() - stamp));
                }
        }
}


СлаваRa 06.09.2014 23:09

Код AS3:

package {
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.text.TextField;
        import flash.utils.getTimer;
        import flash.utils.setTimeout;
 
        /**
        * @author SlavaRa
        */

        public class Main extends Sprite {
 
                public static const COUNT:int = 1000000;
 
                public function Main() {
                        super();
                        _field = new TextField();
                        _field.width = 800;
                        _field.height = 600;
                        addChild(_field);
                        setTimeout(runTests, 1000);
                }
 
                private function runTests():void {
                        testNubideus();//testNubideus:27352
                        testMikroAcse();//testMikroAcse:33144
                        testSlavaRa();//testSlavaRa:23775
                        testNooob();//testNooob:26051
                }
 
                private var _field:TextField;
 
                private function testNubideus():void {
                        var arr:Array = ["Юзернейм", "4", "года", "завтрашний", "только лишь все"];
                        var stamp:int = getTimer();
                        for (var j:int = 0; j < COUNT; j++) {
                                var str:String = "Привет %s, тебе сегодня исполнилось %d %s. Сегодня в %s день могут смотреть не %s. Не скучай, %s!";
                                str.replace(/%s|%d/g, function(substr:String, i:uint, str:String):String {
                                        switch(substr) {
                                                case "%s": return arr.shift();
                                                case "%d": return arr.shift();
                                        }
                                });
                        }
                        _field.appendText("\ntestNubideus:" + (getTimer() - stamp));
                }
 
                private function testMikroAcse():void {
                        var arr:Array = ["Юзернейм", "4", "года", "завтрашний", "только лишь все"];
                        var stamp:int = getTimer();
                        for (var j:int = 0; j < COUNT; j++) {
                                var str:String = "Привет {0}, тебе сегодня исполнилось {1} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!";
                                var len:int = arr.length;
                                for(var i:int = 0; i < len; i++) {
                                        str = str.split("{" + i + "}").join(arr[i]);
                                }
                        }
                        _field.appendText("\ntestMikroAcse:" + (getTimer() - stamp));
                }
 
                private function testSlavaRa():void {
                        var args:Vector.<String> = new <String>["Юзернейм", "4", "года", "завтрашний", "только лишь все"];
                        var stamp:int = getTimer();
                        for (var j:int = 0; j < COUNT; j++) {
                                var str:String = "Привет {0}, тебе сегодня исполнилось {1} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!";
                                str = StringTool.format(str, args);
                        }
                        _field.appendText("\ntestSlavaRa:" + (getTimer() - stamp));
                }
 
                private function testNooob():void {
                        var stamp:int = getTimer();
                        for (var j:int = 0; j < COUNT; j++) {
                                var str:String = "Привет {0}, тебе сегодня исполнилось {1} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!";
                                str = StringUtils.format(str, "Юзернейм", "4", "года", "завтрашний", "только лишь все");
                        }
                        _field.appendText("\ntestNooob:" + (getTimer() - stamp));
                }
        }
 
}
 
class StringTool {
        [Inline]
        public static function format(source:String, args:Vector.<String>):String {
                for(var i:int = args.length; --i >= 0; ) {
                        var pattern:String = "{" + i + "}";
                        label: if(source.indexOf(pattern) != -1) {
                                source = source.replace(pattern, args[i]);
                                goto label;
                        }
                }
                return source;
        }
}
 
class StringUtils
{
        private static const regExp:RegExp = /{(\w)}/g;
        private static var repl:Array;
 
        public static function format(source:String, ...args):String
        {
                repl = args;
                return source.replace(regExp, replaceFunc);
        }
 
        private static function replaceFunc(substr:String, group:int, i:uint, str:String):String
        {
                return repl[group];
        }
}

testNubideus:27352
testMikroAcse:33144
testSlavaRa:23775
testNooob:26051

зы
зачем надо было править мое форматирование?

nubideus 07.09.2014 01:34

x10000
testNubideus:141
testMikroAcse:227
testSlavaRa:174
testNooob:173

> Привет {0}, тебе сегодня исполнилось {1} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!
> Привет Юзернейм, тебе сегодня исполнилось 4 года. Сегодня в завтрашний день могут смотреть не только лишь все. Не скучай, Юзернейм!

> {1{2}{3}{1}}
> {1годазавтрашний4}

> }{}{}{}{}{}{}{}[[[[]}{{}}]]}}{
> }{}{}{}{}{}{}{}[[[[]}{{}}]]}}{

testSlavaRa:
> "{{1}}", ["Юзернейм", "0", "года", "завтрашний", "только лишь все"]
> Юзернейм // wat

testMikroAcse:
>Привет {0}, тебе сегодня исполнилось {{1}} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!
>Привет Юзернейм, тебе сегодня исполнилось только лишь все года. Сегодня в завтрашний день могут смотреть не только лишь все. Не скучай, Юзернейм!

testNooob: жааль что там только от 0 до 9, плюсик дает всего дополнительные 5% времени

Код AS3:

package {
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.text.TextField;
        import flash.utils.getTimer;
        import flash.utils.setTimeout;
 
        /**
        * @author SlavaRa
        */

        public class Main extends Sprite {
 
                public static const COUNT:int = 10000;
 
                public function Main() {
                        super();
                        _field = new TextField();
                        _field.width = 800;
                        _field.height = 600;
                        addChild(_field);
                        setTimeout(runTests, 1000);
                }
 
                private function runTests():void {
                        testNubideus();//testNubideus:27352
                        testMikroAcse();//testMikroAcse:33144
                        testSlavaRa();//testSlavaRa:23775
                        testNooob();//testNooob:26051
                }
 
                private var _field:TextField;
 
                private function testNubideus():void {
                        var stamp:int = getTimer();
                        for (var j:int = 0; j < COUNT; j++) {
                                var arr:Array = ["Юзернейм", "4", "года", "завтрашний", "только лишь все"];
                                var str:String = "Привет {0}, тебе сегодня исполнилось {1} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!";
 
                                var result:String = "";
                                var openIndex:int = -1;
                                var closeIndex:int = -1;
                                parse: while (true) {
                                        openIndex = str.indexOf("{", openIndex + 1);
                                        if (openIndex !== -1) {
                                                sl: for (var i:uint = openIndex + 1; i < str.length; i++ ) {
                                                        switch(str.charAt(i)) {
                                                                case "0": case "1":
                                                                case "2": case "3":
                                                                case "4": case "5":
                                                                case "6": case "7":
                                                                case "8": case "9":
                                                                        continue;
                                                                case "}":
                                                                        break sl;
                                                                default:
                                                                        continue parse;
                                                        }
                                                }
                                                if(openIndex + 1 < i){
                                                        var substr:String = str.substring(openIndex + 1, i);
                                                        result += str.substring(closeIndex + 1, openIndex) + arr[uint(substr)];
                                                        closeIndex = i;
                                                }
                                        }else {
                                                result += str.substring(closeIndex + 1, str.length);
                                                break;
                                        }
                                }
                        }
                        _field.appendText("\ntestNubideus:" + (getTimer() - stamp));
                }
 
                private function testMikroAcse():void {
                        var arr:Array = ["Юзернейм", "4", "года", "завтрашний", "только лишь все"];
                        var stamp:int = getTimer();
                        for (var j:int = 0; j < COUNT; j++) {
                                var str:String = "Привет {0}, тебе сегодня исполнилось {1} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!";
                                var len:int = arr.length;
                                for(var i:int = 0; i < len; i++) {
                                        str = str.split("{" + i + "}").join(arr[i]);
                                }
                        }
                        _field.appendText("\ntestMikroAcse:" + (getTimer() - stamp));
                }
 
                private function testSlavaRa():void {
                        var args:Vector.<String> = new <String>["Юзернейм", "4", "года", "завтрашний", "только лишь все"];
                        var stamp:int = getTimer();
                        for (var j:int = 0; j < COUNT; j++) {
                                var str:String = "Привет {0}, тебе сегодня исполнилось {1} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!";
                                str = StringTool.format(str, args);
                        }
                        _field.appendText("\ntestSlavaRa:" + (getTimer() - stamp));
                }
 
                private function testNooob():void {
                        var stamp:int = getTimer();
                        for (var j:int = 0; j < COUNT; j++) {
                                var str:String = "Привет {0}, тебе сегодня исполнилось {1} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!";
                                str = StringUtils.format(str, "Юзернейм", "4", "года", "завтрашний", "только лишь все");
                        }
                        _field.appendText("\ntestNooob:" + (getTimer() - stamp));
                }
        }
 
}
 
class StringTool {
        [Inline]
        public static function format(source:String, args:Vector.<String>):String {
                for(var i:int = args.length; --i >= 0; ) {
                        var pattern:String = "{" + i + "}";
                        label: if(source.indexOf(pattern) != -1) {
                                source = source.replace(pattern, args[i]);
                                goto label;
                        }
                }
                return source;
        }
}
 
class StringUtils
{
        private static const regExp:RegExp = /{(\w)}/g;
        private static var repl:Array;
 
        public static function format(source:String, ...args):String
        {
                repl = args;
                return source.replace(regExp, replaceFunc);
        }
 
        private static function replaceFunc(substr:String, group:int, i:uint, str:String):String
        {
                return repl[group];
        }
}

+ без проверки на число, 115 мсек
ищет "{", потом ищет первую попавшуюся "}", arr[все что между ними].
если между ними ничего нет, то вставляется {}.
Код AS3:

var arr:Array = ["Юзернейм", "года", "завтрашний", "только лишь все"];
var str:String = "Привет {0}, тебе сегодня исполнилось {length} {1}. Сегодня в {2} день могут смотреть не {3}. Не скучай, {0}!";
 
var result:String = "";
var openIndex:int = -1;
var closeIndex:int = -1;
while (true) {
        openIndex = str.indexOf("{", closeIndex + 1);
        if (openIndex !== -1) {
                var i:int = str.indexOf("}", openIndex + 1);
                if (i === -1) {
                        break;
                }
                if(openIndex + 1 < i){
                        var substr:String = str.substring(openIndex + 1, i);
                        result += str.substring(closeIndex + 1, openIndex) + arr[substr];
                }else {
                        result += "{}";
                }
                closeIndex = i;
        }else break;
}
result += str.substring(closeIndex + 1, str.length);
trace(result); // Привет Юзернейм, тебе сегодня исполнилось 4 года. Сегодня в завтрашний день могут смотреть не только лишь все. Не скучай, Юзернейм!


MikroAcse 07.09.2014 03:40

Вам делать нечего или как? Что это за экозитка в каждой теме, если нужно ПРОСТО решить поставленную задачу?

nubideus 07.09.2014 04:36

MikroAcse, ты первый:
- предложил альтернативное решение
- заикнулся про скорость выполнения.

но в твоем 11 посте ты показываешь самое медленное решение с багом
Цитата:

testMikroAcse:
>Привет {0}, тебе сегодня исполнилось {{1}} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!
>Привет Юзернейм, тебе сегодня исполнилось только лишь все года. Сегодня в завтрашний день могут смотреть не только лишь все. Не скучай, Юзернейм!
должно быть:
> Привет Юзернейм, тебе сегодня исполнилось {4} года. Сегодня в завтрашний день могут смотреть не только лишь все. Не скучай, Юзернейм!
сначала исправь баг, потом уже критикуй

ну и ты не поверишь, решение поставленной задачи в теме всего одно. все остальное - решение задачи из 4 поста

MikroAcse 07.09.2014 13:46

Это не баг, это неправильное использование функции.
Сначала оно заменяет {1} на 4, а потом {4} на "только лишь все".

nubideus 07.09.2014 15:59

MikroAcse,
arr = ["1", "2"]
"{{0}}" // выдаст 2
"{{1}}" // выдаст {2}

либо сделай правильную обработку вложенности, либо убери ее. иначе это баг как не посмотри

MikroAcse 07.09.2014 19:06

Я не делал обработку вложенности, ты неправильно используешь функцию, вот и всё.
На этом я закончу наш разговор.

nubideus 07.09.2014 20:37

parse (str:String, symbol:String, arr:Array) :String{
return "Привет Юзернейм, тебе сегодня исполнилось 4 года. Сегодня в завтрашний день могут смотреть не только лишь все. Не скучай, Юзернейм!";
}

все работает, просто вы идиоты и ниправильна юзаити маю фукнцию

GBee 07.09.2014 23:20

Кстати, а ваши методы учитывают массив замены на более 10 элементов? На детском примере все быстры.
Код AS3:

var elems:Array = ["Ехал", "Грек", "а", "через", "рек", "у", "видит", "в", "е", "рак", "сунул", "руку", "за", "цап"];
var template:String = "{0} {1}{2} {3} {4}{5}, {6} {1}{2} {7} {4}{8} {9}, {10} {1}{2} {7} {4}{5} {11}, {9} {12} {11} {1}{5} {13}!!";

Цитата:

все работает, просто вы идиоты и ниправильна юзаити маю фукнцию
Из серии :o)
Код AS3:

function random():int
{
    return 4;
}

Цитата:

Это не баг, это неправильное использование функции.
Сначала оно заменяет {1} на 4, а потом {4} на "только лишь все".
Это баг, должно быть {4}.

Цитата:

Вам делать нечего или как? Что это за экозитка в каждой теме, если нужно ПРОСТО решить поставленную задачу?
В споре рождается истина. Пока спорящие не переходят на личности и кидаются весомыми аргументами это вообще супер.

nubideus 08.09.2014 03:51

немного поправил. старый тест(x10000) теперь проходит за 130 мсек(было 140 мсек)
Код AS3:

var arr:Array = ["Ехал", "Грек", "а", "через", "рек", "у", "видит", "в", "е", "рак", "сунул", "руку", "за", "цап"];
var str:String = "{0} {1}{2} {3} {4}{5}, {6} {1}{2} {7} {4}{8} {9}, {10} {1}{2} {7} {4}{5} {11}, {9} {12} {11} {1}{5} {13}!!";
 
var result:String = "";
var openIndex:uint = 0;
var closeIndex:uint = 0;
var i:uint = 0;
parse: while (true) {
        openIndex = str.indexOf("{", i) + 1;
        if (openIndex) {
                sl: for (i = openIndex; ; i++ ) {
                        switch(str.charAt(i)) {
                                case "0": case "1":
                                case "2": case "3":
                                case "4": case "5":
                                case "6": case "7":
                                case "8": case "9":
                                        continue;
                                case "}":
                                        break sl;
                                default:
                                        continue parse;
                        }
                }
                if(openIndex < i){
                        var substr:String = str.substring(openIndex, i);
                        result += str.substring(closeIndex, openIndex - 1) + arr[uint(substr)];
                        closeIndex = i + 1;
                }
                continue;
        }
        break;
}
result += str.substring(closeIndex, str.length);
 
trace(result);
// Ехал Грека через реку, видит Грека в реке рак, сунул Грека в реку руку, рак за руку Греку цап!!

Цитата:

Кстати, а ваши методы учитывают массив замены на более 10 элементов? На детском примере все быстры.
у СлаваRa баг тот же, что и у MikroAcse, а у Nooob надо только плюсик в регексп дописать, что бы он стал замечать больше 10.

код СлаваRa и MikroAcse мне не нравится больше не из-за бага, а из-за того, что они не парсят строку, из чего вытекает несколько проблем, помимо бага

СлаваRa 08.09.2014 08:50

Ну так как взяли c# подход к форматированию, я не стал заморачиваться по поводу {{0}} и т.п., т.к. в c# string.Format не проверяет такие вещи, юзаешь - сам себе злобный буратино...
Хотя согласен, что для задачи можно было писать по TDD предусмотрев пару сотен вариантов инпут строки с подвохом)

Цитата:

что они не парсят строку, из чего вытекает несколько проблем, помимо бага
каких?

nubideus 08.09.2014 15:29

Цитата:

в c# string.Format не проверяет такие вещи
"}{", "{}", "{}}" - FormatException

Цитата:

для вывода открывающих и закрывающих фигурных скобок необходимо использовать escape-последовательности. Для вывода открывающей или закрывающей фигурной скобки в фиксированном тексте следует поставить две открывающие или, соответственно, закрывающие фигурные скобки подряд ("{{" или "}}").
Цитата:

Интерпретация вложенных скобок не поддерживается.
т.е. если я напишу "{{0}}", то ничего не будет, выведет "{0}". как и "{{blahblah}}" => "{blahblah}"

Цитата:

c# string.Format не проверяет такие вещи, юзаешь - сам себе злобный буратино...
именно что все проверяет и кидает ошибки.

Цитата:

Цитата:

что они не парсят строку, из чего вытекает несколько проблем, помимо бага
каких?
я думаю, что для тебя и для MikroAcse не будет никаких проблем. ведь вы используете свои функции правильно...

MikroAcse 08.09.2014 16:21

Код AS3:

                        var arr:Array = ["Юзернейм", "4", "года", "завтрашний", "только лишь все"];
                        var str:String = "Привет {0}, тебе сегодня исполнилось {1} {{1}} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!";
                        var res:String = "";
                        var current:String;
                        var nesting:int = 0;
 
                        for (var j:int = 0, l:int = str.length; j < l; j++)
                        {
                                var char:String = str.charAt(j);
 
                                if (char == '{') {
                                        if (nesting == 0) {
                                                current = "";
                                        } else {
                                                current += '{';
                                        }
                                        nesting++;
                                        continue;
                                }
                                if (char == '}') {
                                        if (nesting == 1) {
                                                var parsed:Number = parseFloat(current);
                                                if (isNaN(parsed)) {
                                                        res += "{" + current + "}";
                                                } else {
                                                        res += arr[parsed];
                                                }
                                        } else {
                                                current += '}';
                                        }
                                        nesting--;
                                        continue;
                                }
                                if (nesting == 0) {
                                        res += char;
                                } else {
                                        current += char;
                                }
                        }
 
                        trace(res); // Привет Юзернейм, тебе сегодня исполнилось 4 {{1}} года. Сегодня в завтрашний день могут смотреть не только лишь все. Не скучай, Юзернейм!

Не заменяет вовсе. Так сойдёт? :D

GBee 08.09.2014 17:20

Цитата:

Не заменяет вовсе. Так сойдёт?
Нет. Дерзайте дальше :О)

MikroAcse 08.09.2014 17:24

Цитата:

Сообщение от GBee (Сообщение 1171728)
Нет. Дерзайте дальше :О)

Какой итог тебя устроит?

Nooob 08.09.2014 20:15

псс, парень! не хочешь немного скорости?
Код AS3:

package
{
        import flash.display.Sprite;
        import flash.text.TextField;
        import flash.utils.getTimer;
        import flash.utils.setTimeout;
 
        /**
        * @author SlavaRa
        */

        public class Main extends Sprite
        {
                public static const arr:Vector.<String> = new <String>["Ехал", "Грек", "а", "через", "рек", "у", "видит", "в", "е", "рак", "сунул", "руку", "за", "цап", "0"];
                public static const str:String          = "{0} {1}{2} {3} {4}{5}, {6} {1}{2} {7} {4}{8} {9}, {10} {1}{2} {7} {4}{5} {11}, {9} {12} {11} {1}{5} {13}!! {q} {{14}}";
                public static const COUNT:int = 100000;
 
                public function Main ()
                {
                        super();
                        _field = new TextField();
                        _field.width = 800;
                        _field.height = 600;
                        addChild(_field);
                        setTimeout(runTests, 1000);
                }
 
                private function runTests ():void
                {
                        testNubideus();
                        testMikroAcse();
                        testSlavaRa();
                        testNooob();
                }
 
                private var _field:TextField;
 
                private function testNubideus ():void
                {
                        var stamp:int          = getTimer();
                        for (var j:int = 0; j < COUNT; j++)
                        {
                                var result:String = "";
                                var openIndex:uint = 0;
                                var closeIndex:uint = 0;
                                var i:uint = 0;
                                parse: while (true) {
                                        openIndex = str.indexOf("{", i) + 1;
                                        if (openIndex) {
                                                sl: for (i = openIndex; ; i++ ) {
                                                        switch(str.charAt(i)) {
                                                                case "0": case "1":
                                                                case "2": case "3":
                                                                case "4": case "5":
                                                                case "6": case "7":
                                                                case "8": case "9":
                                                                        continue;
                                                                case "}":
                                                                        break sl;
                                                                default:
                                                                        continue parse;
                                                        }
                                                }
                                                if(openIndex < i){
                                                        var substr:String = str.substring(openIndex, i);
                                                        result += str.substring(closeIndex, openIndex - 1) + arr[uint(substr)];
                                                        closeIndex = i + 1;
                                                }
                                                continue;
                                        }
                                        break;
                                }
                                result += str.substring(closeIndex, str.length);
                        }
                        _field.appendText("\ntestNubideus:" + (getTimer() - stamp));
                        _field.appendText("\n" + result);
                }
 
                private function testMikroAcse ():void
                {
                        var stamp:int = getTimer();
                        for (var j1:int = 0; j1 < COUNT; j1++)
                        {
                                var res:String = "";
                                var current:String;
                                var nesting:int = 0;
                                for (var j:int = 0, l:int = str.length; j < l; j++)
                                {
                                        var char:String = str.charAt(j);
 
                                        if (char == '{') {
                                                if (nesting == 0) {
                                                        current = "";
                                                } else {
                                                        current += '{';
                                                }
                                                nesting++;
                                                continue;
                                        }
                                        if (char == '}') {
                                                if (nesting == 1) {
                                                        var parsed:Number = parseFloat(current);
                                                        if (isNaN(parsed)) {
                                                                res += "{" + current + "}";
                                                        } else {
                                                                res += arr[parsed];
                                                        }
                                                } else {
                                                        current += '}';
                                                }
                                                nesting--;
                                                continue;
                                        }
                                        if (nesting == 0) {
                                                res += char;
                                        } else {
                                                current += char;
                                        }
                                }
                        }
                        _field.appendText("\ntestMikroAcse:" + (getTimer() - stamp));
                        _field.appendText("\n" + res);
                }
 
                private function testSlavaRa ():void
                {
                        var stamp:int            = getTimer();
                        for (var j:int = 0; j < COUNT; j++)
                        {
                                var result:String = StringTool.format(str, arr);
                        }
                        _field.appendText("\ntestSlavaRa:" + (getTimer() - stamp));
                        _field.appendText("\n" + result);
                }
 
                private function testNooob ():void
                {                       
                        var stamp:int          = getTimer();
                        for (var j:int = 0; j < COUNT; j++)
                        {
                                var result:String = StringUtilsFast.format(str, arr);
                        }
                        _field.appendText("\ntestNooob:" + (getTimer() - stamp));
                        _field.appendText("\n" + result);
                }
        }
}
 
import flash.system.ApplicationDomain;
import flash.utils.ByteArray;
 
import avm2.intrinsics.memory.li32;
import avm2.intrinsics.memory.li8;
import avm2.intrinsics.memory.si32;
 
class StringUtilsFast
{
        private static const bytes:ByteArray = new ByteArray();
        bytes.length = ApplicationDomain.MIN_DOMAIN_MEMORY_LENGTH;
 
        [Inline]
        public static function format (source:String, args:Vector.<String>):String
        {
                var mem:ByteArray = ApplicationDomain.currentDomain.domainMemory;
                ApplicationDomain.currentDomain.domainMemory = bytes;
                var ptr:int = 0;
                var n:int  = source.length;
                for (var i:int = 0; i < n; i++)
                {
                        si32(source.charCodeAt(i), ptr += 4);
                }
                var result:String = "";
                var openIndex:int = -1;
                i = 0;
                n = ptr;
                while (i < n)
                {
                        var charCode:uint = li32(i += 4);
                        if (openIndex != -1)
                        {
                                if (charCode == 125)
                                {
                                        var index:int = 0;
                                        var count:int = 1;
                                        for (var k:int = openIndex + 4; k < i; k += 4)
                                        {
                                                var code:uint = li32(k);
                                                if (code >= 48 && code <= 57)
                                                {
                                                        index = index * count + (code - 48);
                                                        count *= 10;
                                                        continue;
                                                }
                                                index = -1;
                                                break;
                                        }
                                        if (index != -1)
                                        {
                                                result += args[index];
                                                openIndex = -1;
                                                continue;
                                        }
                                        var h:int = i + 4;
                                        for (k = openIndex; k < h; k += 4)
                                        {
                                                result += String.fromCharCode(li32(k));
                                        }
                                        openIndex = -1;
                                        continue;
                                }
                                if (charCode == 123)
                                {
                                        for (k = openIndex; k < i; k += 4)
                                        {
                                                result += String.fromCharCode(li32(k));
                                        }
                                        openIndex = i;
                                        continue;
                                }
                                continue;
                        }
                        if (charCode == 123)
                        {
                                openIndex = i;
                                continue;
                        }
                        result += String.fromCharCode(charCode);
                }
                ApplicationDomain.currentDomain.domainMemory = mem;
                return result;
        }
}
 
class StringTool
{
        [Inline]
        public static function format(source:String, args:Vector.<String>):String {
                for(var i:int = args.length; --i >= 0; ) {
                        var pattern:String = "{" + i + "}";
                        label: if(source.indexOf(pattern) != -1) {
                                source = source.replace(pattern, args[i]);
                                goto label;
                        }
                }
                return source;
        }
}

testNubideus:1130
Ехал Грека через реку, видит Грека в реке рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} {0}

testMikroAcse:1335
Ехал Грека через реку, видит Грека в реке рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} {{14}}

testSlavaRa:2638
Ехал Грека через реку, видит Грека в реке рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} Ехал

testNooob:746
Ехал Грека через реку, видит Грека в реке рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} {0}

GBee 08.09.2014 20:25

Цитата:

Какой итог тебя устроит?
дано
"{0} {{1}}"
["1", "год"]

результат
"1 {год}"

nubideus 08.09.2014 21:01

> result += String.fromCharCode(
Nooob, прикрути substring, а то если увеличить расстояние между вставками, скорость упадет

Цитата:

x10000
testNubideus:546
Ехал _____ Грек _____ а _____ через _____ рек _____ у, видит _____ Грек _____ а в _____ рек _____ е рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} {0}
testMikroAcse:699
Ехал _____ Грек _____ а _____ через _____ рек _____ у, видит _____ Грек _____ а в _____ рек _____ е рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} {{14}}
testSlavaRa:869
Ехал _____ Грек _____ а _____ через _____ рек _____ у, видит _____ Грек _____ а в _____ рек _____ е рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} Ехал
testNooob:600
Ехал _____ Грек _____ а _____ через _____ рек _____ у, видит _____ Грек _____ а в _____ рек _____ е рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} {0}
+ у тебя пустые скобки считаются за ноль ({} = {0}), и игнорится { в конце
короче строка "{0} {} {"
Цитата:

testNubideus:64
Ехал {} {
testMikroAcse:49
Ехал {}
testSlavaRa:151
Ехал {} {
testNooob:39
Ехал Ехал

Nooob 08.09.2014 21:33

ага, исправил
Код AS3:

class StringUtils
{
        [Inline]
        public static function format (source:String, args:Vector.<String>):String
        {
                var result:String = "";
                var openIndex:int = -1;
                var charCount:int = 0;
                var n:int = source.length;
                var a:int = args.length;
                var i:int = 0;
                l3: if(i < n)
                {
                        var char:String = source.charAt(i);
                        if (openIndex != -1)
                        {
                                if (char == "}")
                                {
                                        var start:int = openIndex + 1;
                                        if(start == i)
                                        {
                                                goto l1;
                                        }
                                        var argsIndex:int = 0;
                                        var tenths:int = 1;
                                        l2:if (start < i)
                                        {
                                                var code:uint = source.charCodeAt(start);
                                                if (code >= 48 && code <= 57)
                                                {
                                                        argsIndex = argsIndex * tenths + (code - 48);
                                                        tenths *= 10;
                                                        start++;
                                                        goto l2;
                                                }
                                                goto l1;
                                        }
                                        if (argsIndex < a)
                                        {
                                                result += source.substr(openIndex - charCount, charCount);
                                                charCount = 0;
                                                result += args[argsIndex];
                                                openIndex = -1;
                                                i++;
                                                goto l3;
                                        }
                                        l1:
                                        result += source.substring(openIndex - charCount, i + 1);
                                        charCount = 0;
                                        openIndex = -1;
                                        i++;
                                        goto l3;
                                }
                                if (char == "{")
                                {
                                        result += source.substring(openIndex - charCount, i);
                                        charCount = 0;
                                        openIndex = i;
                                        i++;
                                        goto l3;
                                }
                                i++;
                                goto l3;
                        }
                        if (char == "{")
                        {
                                openIndex = i;
                                i++;
                                goto l3;
                        }
                        charCount++;
                        i++;
                        goto l3;
                }
                if(openIndex != -1)
                {
                        result += source.substring(openIndex - charCount, i + 1);
                }
                else if (charCount > 0)
                {
                        result += source.substr(i - charCount, charCount);
                }
                return result;
        }
}

в целом, не важно как написано, главное чтобы не было преобразования строки в число, а преобразовывать по чар кодам.
Код AS3:

                                        var index:int = 0;
                                        var tenths:int = 1;
                                        while(start < end)
                                        {
                                                var code:uint = source.charCodeAt(start);
                                                if (code >= 48 && code <= 57)
                                                {
                                                        index = index * tenths + (code - 48);
                                                        tenths *= 10;
                                                        start++;
                                                        continue;
                                                }
                                                break;
                                        }

Я вот только не понимаю, какие то адские различия между дебаг и релиз плеером
x100000
Релиз:
testNubideus:1082
testNooob:692
Дебаг:
testNubideus:4162
testNooob:6135

в чем причина разницы в 10 раз в принипе понятно, но не понятно почему одни и те же алгоритмы в релизе кажут лучше чем в дебаге? в релизе есть NanoJIT? оверхед на хранение стека? разница GC?

GBee 08.09.2014 22:56

Nooob, а goto вам что-то дает, или это привычка с других языков?

Nooob 08.09.2014 23:44

не, решил попробовать просто, никогда раньше не пользовался, так как ситуаций не было. а тут не хотел просто ту же самую операцию вешать на continue goto, break goto.

nubideus 09.09.2014 00:55

x100000
Цитата:

testNubideus:3256
Ехал Грека через реку, видит Грека в реке рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} {0} {} {
testMikroAcse:5090
Ехал Грека через реку, видит Грека в реке рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} {{14}} {}
testSlavaRa:8296
Ехал Грека через реку, видит Грека в реке рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} Ехал {} {
testNooob:3643
Ехал Грека через реку, видит Грека в реке рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} {0} {}
Код AS3:

package
{
        import flash.display.Sprite;
        import flash.text.TextField;
        import flash.utils.getTimer;
        import flash.utils.setTimeout;
 
        /**
        * @author SlavaRa
        */

        public class Main extends Sprite
        {
                public static const arr:Vector.<String> = new <String>["Ехал", "Грек", "а", "через", "рек", "у", "видит", "в", "е", "рак", "сунул", "руку", "за", "цап", "0"];
                public static const str:String          = "{0} {1}{2} {3} {4}{5}, {6} {1}{2} {7} {4}{8} {9}, {10} {1}{2} {7} {4}{5} {11}, {9} {12} {11} {1}{5} {13}!! {q} {{14}} {} {";
                public static const COUNT:int = 100000;
 
                public function Main ()
                {
                        super();
                        _field = new TextField();
                        _field.width = 800;
                        _field.height = 600;
                        addChild(_field);
                        setTimeout(runTests, 1000);
                }
 
                private function runTests ():void
                {
                        testNubideus();
                        testMikroAcse();
                        testSlavaRa();
                        testNooob();
                }
 
                private var _field:TextField;
 
                private function testNubideus ():void
                {
                        var stamp:int          = getTimer();
                        for (var j:int = 0; j < COUNT; j++)
                        {
                                var result:String = "";
                                var openIndex:uint = 0;
                                var closeIndex:uint = 0;
                                var i:uint = 0;
                                parse: while (true) {
                                        openIndex = str.indexOf("{", i) + 1;
                                        if (openIndex) {
                                                var index:uint = 0;
                                                for (i = openIndex; ; i++ ) {
                                                        var code:uint = str.charCodeAt(i);
                                                        //if ((code + 2147483551 | 0) >= 2147483599) {
                                                        if (code >= 48 && code <= 57) {
                                                                index = index * 10 + (code - 48);
                                                                continue;
                                                        }else if (code === 125) { // if "}"
                                                                break;
                                                        }
                                                        continue parse;
                                                }
                                                if (openIndex < i) {
                                                        result += str.substring(closeIndex, openIndex - 1) + arr[index];
                                                        closeIndex = i + 1;
                                                }
                                                continue;
                                        }
                                        result += str.substring(closeIndex, str.length);
                                        break;
                                }
                        }
                        _field.appendText("\ntestNubideus:" + (getTimer() - stamp));
                        _field.appendText("\n" + result);
                }
 
                private function testMikroAcse ():void
                {
                        var stamp:int = getTimer();
                        for (var j1:int = 0; j1 < COUNT; j1++)
                        {
                                var res:String = "";
                                var current:String;
                                var nesting:int = 0;
                                for (var j:int = 0, l:int = str.length; j < l; j++)
                                {
                                        var char:String = str.charAt(j);
 
                                        if (char == '{') {
                                                if (nesting == 0) {
                                                        current = "";
                                                } else {
                                                        current += '{';
                                                }
                                                nesting++;
                                                continue;
                                        }
                                        if (char == '}') {
                                                if (nesting == 1) {
                                                        var parsed:Number = parseFloat(current);
                                                        if (isNaN(parsed)) {
                                                                res += "{" + current + "}";
                                                        } else {
                                                                res += arr[parsed];
                                                        }
                                                } else {
                                                        current += '}';
                                                }
                                                nesting--;
                                                continue;
                                        }
                                        if (nesting == 0) {
                                                res += char;
                                        } else {
                                                current += char;
                                        }
                                }
                        }
                        _field.appendText("\ntestMikroAcse:" + (getTimer() - stamp));
                        _field.appendText("\n" + res);
                }
 
                private function testSlavaRa ():void
                {
                        var stamp:int            = getTimer();
                        for (var j:int = 0; j < COUNT; j++)
                        {
                                var result:String = StringTool.format(str, arr);
                        }
                        _field.appendText("\ntestSlavaRa:" + (getTimer() - stamp));
                        _field.appendText("\n" + result);
                }
 
                private function testNooob ():void
                {                       
                        var stamp:int          = getTimer();
                        for (var j:int = 0; j < COUNT; j++)
                        {
                                var result:String = StringUtilsFast.format(str, arr);
                        }
                        _field.appendText("\ntestNooob:" + (getTimer() - stamp));
                        _field.appendText("\n" + result);
                }
        }
}
 
import flash.system.ApplicationDomain;
import flash.utils.ByteArray;
 
import avm2.intrinsics.memory.li32;
import avm2.intrinsics.memory.li8;
import avm2.intrinsics.memory.si32;
 
class StringUtilsFast
{
        [Inline]
        public static function format (source:String, args:Vector.<String>):String
        {
                var result:String = "";
                var openIndex:int = -1;
                var charCount:int = 0;
                var n:int = source.length;
                var a:int = args.length;
                var i:int = 0;
                l3: if(i < n)
                {
                        var char:String = source.charAt(i);
                        if (openIndex != -1)
                        {
                                if (char == "}")
                                {
                                        if(openIndex == i)
                                        {
                                                goto l1;
                                        }
                                        var argsIndex:int = 0;
                                        var count:int = 1;
                                        var k:int = openIndex;
                                        l2:if (k < i)
                                        {
                                                var code:uint = source.charCodeAt(k);
                                                if (code >= 48 && code <= 57)
                                                {
                                                        argsIndex = argsIndex * count + (code - 48);
                                                        count *= 10;
                                                        k++;
                                                        goto l2;
                                                }
                                                goto l1;
                                        }
                                        if (argsIndex < a)
                                        {
                                                result += source.substr(openIndex - charCount - 1, charCount);
                                                charCount = 0;
                                                result += args[argsIndex];
                                                openIndex = -1;
                                                i++;
                                                goto l3;
                                        }
                                        l1:
                                        result += source.substring(openIndex - charCount - 1, i + 1);
                                        charCount = 0;
                                        openIndex = -1;
                                        i++;
                                        goto l3;
                                }
                                if (char == "{")
                                {
                                        result += source.substring(openIndex - charCount - 1, i);
                                        charCount = 0;
                                        openIndex = i + 1;
                                        i++;
                                        goto l3;
                                }
                                i++;
                                goto l3;
                        }
                        if (char == "{")
                        {
                                openIndex = i + 1;
                                i++;
                                goto l3;
                        }
                        charCount++;
                        i++;
                        goto l3;
                }
                return result;
        }
}
 
class StringTool
{
        [Inline]
        public static function format(source:String, args:Vector.<String>):String {
                for(var i:int = args.length; --i >= 0; ) {
                        var pattern:String = "{" + i + "}";
                        label: if(source.indexOf(pattern) != -1) {
                                source = source.replace(pattern, args[i]);
                                goto label;
                        }
                }
                return source;
        }
}

Цитата:

Я вот только не понимаю, какие то адские различия между дебаг и релиз плеером
там после каждого переноса строки добавляются байты отладки, т.е. так получается потому что у тебя просто строк больше в коде. ну и мб charAt медленнее в дебаге

идею бессовестно урал, зато нашел баг.

допустим строка 123:
0 * 1 + 1
1 * 10 + 2
12 * 100 + 3
= 1203

можно просто умножать на 10:
0 * 10 + 1
1 * 10 + 2
12 * 10 + 3
= 123

кстати у тебя последняя открытая скобка игнорится

Nooob 09.09.2014 05:17

nubideus, ну всё, теперь я думаю что это самый быстрый вариант =)


Часовой пояс GMT +4, время: 21:11.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.