|
|
|||||
Регистрация: Feb 2012
Сообщений: 1,540
|
Медленный, но менее морочный вариант
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); Последний раз редактировалось MikroAcse; 06.09.2014 в 21:37. |
|
|||||
Небольшой тестик по теме
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)); } } } UPD1: самый быстрый Inline вариант, стабильно 4 сек. на миллион
__________________
местонахождение Последний раз редактировалось СлаваRa; 06.09.2014 в 23:11. |
|
|||||
Регистрация: Mar 2007
Сообщений: 319
|
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 |
|
|||||
тест вашего и моего кода, в release(миллион итераций)
testSlavaRa:4100 testNooob:20680 все 4 теста с вашим кодом падают по таймауту UPD1: + ваш спокойно себе заменит и {a}, {b}, {c}, ... чего делать не должен(
__________________
местонахождение Последний раз редактировалось СлаваRa; 06.09.2014 в 22:54. |
|
|||||
Регистрация: Jan 2013
Сообщений: 322
|
Цитата:
>Сегодня в %s день могут смотреть не %s. Не скучай, {0}! >Сегодня в завтрашний день могут смотреть не только лишь все. Не скучай, {0}! тут ошибка в том, что ты не тот код скопировал. ну и в регекспе лишний плюсик /{[0-9]+}+/g, но и с ним работает, так что не стал править вы не сможете отладить, если в строке будет {n}, где n больше или равно arg.length, по идее должно выдавать range error. я этого не учел потому что пофиг ваще например "asd asd {9999} sad" |
|
|||||
Извиняюсь, да.. мой косяк, исправил сообщение.
__________________
местонахождение |
|
|||||
Регистрация: Mar 2007
Сообщений: 319
|
ну ещёб, у тебя там ошибки в коде, в следующей итерации str будет уже старый и поэтому будет работать быстрее.
если уж инлайнить то 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)); } } } |
|
|||||
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]; } } testMikroAcse:33144 testSlavaRa:23775 testNooob:26051 зы зачем надо было править мое форматирование?
__________________
местонахождение |
|
|||||
Регистрация: Jan 2013
Сообщений: 322
|
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% времени 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]; } } ищет "{", потом ищет первую попавшуюся "}", arr[все что между ними]. если между ними ничего нет, то вставляется {}. 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 года. Сегодня в завтрашний день могут смотреть не только лишь все. Не скучай, Юзернейм! Последний раз редактировалось nubideus; 07.09.2014 в 02:16. |
|
|||||
Регистрация: Feb 2012
Сообщений: 1,540
|
Вам делать нечего или как? Что это за экозитка в каждой теме, если нужно ПРОСТО решить поставленную задачу?
|
Часовой пояс GMT +4, время: 18:00. |
|
« Предыдущая тема | Следующая тема » |
|
|